Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как удалить <script> ? (https://javascript.ru/forum/misc/44604-kak-udalit-script.html)

Danxil 25.01.2014 23:10

Как удалить <script> ?
 
Пишу модуль для joomla. При загрузке модуля, из php-файла вставляется <script> такого вида:
<script>
		(function($)
		{
			$(document).ready(function()
			{
				if (!$(document).bxSlider)
				{
					var script = document.createElement("script");
						
					script.type = "text/javascript";
					script.src = "<?php echo JURI::root()?>modules/mod_ext_jshopping_slider_products/assets/js/jquery.bxSlider.min.js";
						
					$("head").append(script);
				}
				$("#slider__list_<?php echo $id_sfx; ?>").bxSlider();
			});
		})(jQuery)
</script>


Как удалить этот <script> после того, как он отработан, не создавая при этом новых скриптов на странице ?

melky 25.01.2014 23:28

пометь скрипт ID'шником и
$('#foo').remove();

только непонятно, зачем

Vlasenko Fedor 25.01.2014 23:29

Как подключать скрипты описал здесь
http://joomlaforum.ru/index.php/topi...tml#msg1240518
Тег скрипт конечно можно и удалить, только смысл в этом какой и для чего

Danxil 25.01.2014 23:37

Цитата:

Сообщение от melky (Сообщение 294072)
пометь скрипт ID'шником и
$('#foo').remove();

только непонятно, зачем

Что бы выполнить
$('#foo').remove();

нужно создать еще один скрипт, который потом тоже нужно будет удалить. Удалять для того что бы страница не захламлялась скриптами.

Danxil 25.01.2014 23:50

Цитата:

Сообщение от melky (Сообщение 294072)
пометь скрипт ID'шником и
$('#foo').remove();

только непонятно, зачем

Цитата:

Сообщение от Poznakomlus (Сообщение 294073)
Как подключать скрипты описал здесь
http://joomlaforum.ru/index.php/topi...tml#msg1240518
Тег скрипт конечно можно и удалить, только смысл в этом какой и для чего

Сначала я так и делал
$doc->addScriptDeclaration($js); //вставляем код js

все ок если модуль используется только в одном месте на странице, но если в двух, то содержимое $js-ов вставлялось в один и тот же скрипт выдавало ошибку

Vlasenko Fedor 26.01.2014 00:04

Цитата:

Сообщение от Danxil
Удалять для того что бы страница не захламлялась скриптами

Для этого есть плагины объединения скриптов к примеру предложенный здесь http://joomlaforum.ru/index.php/topi...tml#msg1198234
вы можете инициализировать статическую переменную и в зависимости от ее состояния подключать скрипт, также вы можете проверить находится ли данный скрипт в массиве $this->_scripts ($doc->_scripts)
тематика данного решения не связана с этим форумом никак

Danxil 26.01.2014 00:08

Фу я туплю, нормально удалил по id)

Цитата:

Сообщение от Poznakomlus (Сообщение 294082)
Для этого есть плагины объединения скриптов к примеру предложенный здесь http://joomlaforum.ru/index.php/topi...tml#msg1198234
вы можете инициализировать статическую переменную и в зависимости от ее состояния подключать скрипт, также вы можете проверить находится ли данный скрипт в массиве $this->_scripts ($doc->_scripts)
тематика данного решения не связана с этим форумом никак

Спс, посмотрю

melky 26.01.2014 00:40

Цитата:

Сообщение от Danxil (Сообщение 294077)
Что бы выполнить
$('#foo').remove();

нужно создать еще один скрипт, который потом тоже нужно будет удалить. Удалять для того что бы страница не захламлялась скриптами.

что? зачем?
вы пробовали, прежде чем отвергать?

Цитата:

Сообщение от Poznakomlus
тематика данного решения не связана с этим форумом никак

джумла не умеет агрегировать скрипты?

danik.js 26.01.2014 07:42

Цитата:

Сообщение от Danxil
Удалять для того что бы страница не захламлялась скриптами.

Гениально! Пойду чистить свои проекты от скриптов. Это ж сколько хлама!!! :lol:

danik.js 26.01.2014 07:49

Я вобще как-то сомневаюсь что код скрипта отработает без ошибки. После окончания парсинга документа скрипты исполняются асинхронно, так что нельзя взять просто так и сразу после добавления скрипта вызвать из него функцию - файл попросту не успеет к этому моменту загрузиться или исполниться.

melky 26.01.2014 10:38

Цитата:

Сообщение от danik.js (Сообщение 294120)
Я вобще как-то сомневаюсь что код скрипта отработает без ошибки. После окончания парсинга документа скрипты исполняются асинхронно, так что нельзя взять просто так и сразу после добавления скрипта вызвать из него функцию - файл попросту не успеет к этому моменту загрузиться или исполниться.

думаешь, он в оперативную память не залезет?

danik.js 26.01.2014 11:19

melky я не понимаю к чему ты клонишь. Впрочем я оказался не прав: даже во время парсинга скрипт исполнится асинхронно:
<script>
    var script = document.createElement('script');
    script.src = 'data:application/javascript,function%09fn(){alert("ok")}';
    document.head.appendChild(script);
    fn();
</script>


<script>
document.addEventListener('DOMContentLoaded', function(){
    var script = document.createElement('script');
    script.src = 'data:application/javascript,function%09fn(){alert("ok")}';
    document.head.appendChild(script);
    fn();
});
</script>

рони 26.01.2014 11:31

danik.js,
интересно что должны продемонстрировать примеры, когда нажмёшь кнопку посмотреть. куда смотреть чего ждать?

danik.js 26.01.2014 12:38

Цитата:

Сообщение от рони
куда смотреть чего ждать?

Консоль открой. Увидишь ошибку что функция fn не определена.

Синхронно скрипт можно вставить через document.write() во время парсинга.

рони 26.01.2014 12:58

danik.js,
:write: а так? или это не про то?
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
</head>

<body>
<script>
document.addEventListener('DOMContentLoaded', function(){
    var script = document.createElement('script');
    script.src = 'data:application/javascript,function%09fn(){alert("ok")}';
    document.head.appendChild(script);
    window.setTimeout('fn()', 0)
    //fn();
});
</script>

</body>

</html>

Vlasenko Fedor 26.01.2014 13:06

какой смысл удаять тег если скрипт будет все равно в памяти?
можете перегрузить обернув все в фунцию, но все эти действия похожи на извращенческие, с неправильной архитектурой и порядком действий

Danxil 26.01.2014 13:27

Цитата:

Сообщение от Poznakomlus (Сообщение 294146)
какой смысл удаять тег если скрипт будет все равно в памяти?
можете перегрузить обернув все в фунцию, но все эти действия похожи на извращенческие, с неправильной архитектурой и порядком действий

Т.е. нормально, если скрипт после выполнения так и останется висеть на странице ?

Так он и обернут в функцию
<script>
        (function($)
        {
            $(document).ready(function()
            {
                if (!$(document).bxSlider)
                {
                    var script = document.createElement("script");
                         
                    script.type = "text/javascript";
                    script.src = "<?php echo JURI::root()?>modules/mod_ext_jshopping_slider_products/assets/js/jquery.bxSlider.min.js";
                         
                    $("head").append(script);
                }
                $("#slider__list_<?php echo $id_sfx; ?>").bxSlider();
            });
        })(jQuery)
</script>

Vlasenko Fedor 26.01.2014 13:33

Цитата:

Сообщение от Danxil
Т.е. нормально, если скрипт после выполнения так и останется висеть на странице

Что значит висеть на странице?
Всегда выносите js код в отдельные файлы, не засоряйте html разметку страницы

Danxil 26.01.2014 13:58

Цитата:

Сообщение от Poznakomlus (Сообщение 294157)
Что значит висеть на странице?
Всегда выносите js код в отдельные файлы, не засоряйте html разметку страницы

Дело в том, что в самом скрипте я использую пхп, в примере выше видно. Т.е. если подключать файл, то нужно подключать script.php, а не script.js
соответсвенно из этого пхп-файла будет в любом случае на страницу вставлятся тег script

Vlasenko Fedor 26.01.2014 14:37

Цитата:

Сообщение от Danxil
Дело в том, что в самом скрипте я использую пхп, в примере выше видно

что мешает прописать значения php переменных вручную
и пример с <script src="/script.php" type="text/javascript"></script> также имеет право на жизнь
где код script.php
<?php
header('Content-type: text/javascript; charset: UTF-8');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT');
header("Content-Encoding: gzip"); //сжатие если не работает удалить строку
header('Last-Modified: '.gmdate('D, d M Y H:i:s',filemtime(__FILE__)).' GMT');
?>
//здесь уже js
alert('Work');

melky 26.01.2014 14:47

Цитата:

Сообщение от danik.js (Сообщение 294130)
melky я не понимаю к чему ты клонишь.

Цитата:

Сообщение от Poznakomlus (Сообщение 294146)
какой смысл удаять тег если скрипт будет все равно в памяти?

вот это я имел в виду. Скрипт на момент "удаления" уже пропарсен движком JS с скомпилен в байт-код (неоптимизированный).


Цитата:

Сообщение от danik.js (Сообщение 294130)
Впрочем я оказался не прав: даже во время парсинга скрипт исполнится асинхронно:
<script>
    var script = document.createElement('script');
    script.src = 'data:application/javascript,function%09fn(){alert("ok")}';
    document.head.appendChild(script);
    fn();
</script>


<script>
document.addEventListener('DOMContentLoaded', function(){
    var script = document.createElement('script');
    script.src = 'data:application/javascript,function%09fn(){alert("ok")}';
    document.head.appendChild(script);
    fn();
});
</script>

что?

попробуй достать до <body> из <head>, если они исполняются асинхронно. Парсер HTML приостанавливается, когда встречает <script>. Продолжает работу, когда <script> пропарсен.

твой первый пример полностью подтверждает это :)

<html>
<head>
<script>
try {
    alert( 'document.getElementsByTagName("body").length: ' +  document.getElementsByTagName("body").length );
} catch (e) {
    alert( 'ошибка при доступе к document.getElementsByTagName("body").length \n\n\t' + e.message  );
}
</script>
</head>
<body>Должен быть алерт</body>
</html>


асинхронно (не задерживая парсер HTML) скрипты загружаются, если их пометить атрибутом async (в старых IE называется defer). Но это не даёт никаких гарантий, что этот асинхронный скрипт будет работать после парсинга дерева.

Cори за оффтоп.

danik.js 26.01.2014 15:15

Цитата:

Сообщение от melky
что?

Я не о том. Понятно что вставленный парсером скрипт исполняется тут же, а парсер ждет. Я о том, что внешний скрипт, вставленный во время парсинга юзером (через appendChild) будет исполнен асинхронно. Если не ошибаюсь, все внешние скрипты (то есть имеющие [src]), вставленные через appendChild, помечаются как асинхронные.

Но я вновь ошибся. Если вставлять скрипт даже синхронно, через document.write, то конечно же он исполнится только когда текущий скрипт отработает. Я просто запутался. Есть еще вариант вставки через appendChild инлайн-скрипта. Так вот он отработает незамедлительно, прям в момент вставки.

Вставка через appendChild, не сработает, так как это внешний скрипт, вставленный юзером (отрабатывает всегда асинхронно).
<script>
	var script = document.createElement('script');
	script.src = 'data:application/javascript,function%09fn(){alert("ok")}';
	document.head.appendChild(script);
</script>
<script>
	fn();
</script>


Вставка через document.write, сработает, так как скрипт будет разобран парсером сразу же и отправлен на выполнение.
<script>
	var script = document.createElement('script');
	script.src = 'data:application/javascript,function%09fn(){alert("ok")}';
	document.write('<script src=\'data:application/javascript,function%09fn(){alert("ok")}\'><\/script>');
</script>
<script>
	fn();
</script>


Сработает, чем-то похоже на eval.
<script>
	var script = document.createElement('script');
	script.innerText = 'function fn() {alert("ok")}';
	document.head.appendChild(script);
	fn();
</script>

danik.js 26.01.2014 15:21

Цитата:

Сообщение от рони
а так? или это не про то?

Нет гарантий, что сработает. Сработает только когда скрипт закэширован.Danxil, может ты прокомментируешь ситуацию со своим кодом? Он не может работать ну никак.
Цитата:

Сообщение от Poznakomlus
header("Content-Encoding: gzip"); //сжатие если не работает удалить строку

В каком смысле не работает? Мож ты думаешь что сжатие происходит путем установки заголовка?

Danxil 26.01.2014 15:26

Цитата:

Сообщение от Poznakomlus (Сообщение 294169)
что мешает прописать значения php переменных вручную
и пример с <script src="/script.php" type="text/javascript"></script> также имеет право на жизнь
где код script.php
<?php
header('Content-type: text/javascript; charset: UTF-8');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT');
header("Content-Encoding: gzip"); //сжатие если не работает удалить строку
header('Last-Modified: '.gmdate('D, d M Y H:i:s',filemtime(__FILE__)).' GMT');
?>
//здесь уже js
alert('Work');

Вручную нельзя прописать потому что значение одной из переменных генерируется рандомно
$id_sfx = rand(1,100) . rand(1,100);
, ну и вообще хардкод фигачить не тру.
Попробовал подключить файл с заголовками - пишет ошибку как только доходит до первой php-вставки
<?php
	header('Content-type: text/javascript; charset: UTF-8');
	header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT');
	header('Last-Modified: '.gmdate('D, d M Y H:i:s',filemtime(__FILE__)).' GMT');
?>

(function($)
{
	$(document).ready(function()
	{
		if (!$(document).bxSlider)
		{
			var script = document.createElement("script");
			
			script.type = "text/javascript";
			
			
			
			script.src = "<?php echo JURI::root() ?>/modules/mod_ext_jshopping_slider_products/assets/js/jquery.bxSlider.min.js"; // тут ошибка Unexpected token ILLEGAL

Vlasenko Fedor 26.01.2014 15:31

Цитата:

Сообщение от danik.js
В каком смысле не работает

не сработает если сервер будет сжимать используя другие методы сжатия
я не зря так написал, потому как сталкивался на разных серверах с разными настройками данная строка может быть причиной ошибки
а это доки http://tools.ietf.org/html/rfc2616#section-14.3

melky 26.01.2014 15:45

Цитата:

Сообщение от danik.js (Сообщение 294174)
...

итог:


похоже что да, асинхронно.
странно, почему при document.write он не отправляется на "загрузку".
наверное, связано с механизом парсинга и нужно неплохо знать всё это дело, чтобы разобраться.

Vlasenko Fedor 26.01.2014 15:45

Цитата:

Сообщение от Danxil
$id_sfx = rand(1,100) . rand(1,100);

var id_sfx = Math.random() * 10000;

можно заменить

Danxil 26.01.2014 15:51

Цитата:

Сообщение от Poznakomlus (Сообщение 294181)
var id_sfx = Math.random() * 10000;

можно заменить

Я использую эту переменную при выводе верстки, нужно именно на пхп
<ul class="slider__list" id="slider__list_<?php echo $id_sfx; ?>">
<?php foreach($last_prod as $curr){ ?>
	<li>
        //...

Vlasenko Fedor 26.01.2014 16:09

Danxil,
это генератор случайных чисел, используй себе на php свой на js cвой
они генерируют разные значения и уже попахивает на г-код ибо незачем добавлять каждый раз свой ид. В модулях Joomla для разделения мух от котлет, достаточно было добавляеть ид модуля
$module->id

Danxil 26.01.2014 16:22

Цитата:

Сообщение от Poznakomlus (Сообщение 294183)
Danxil,
это генератор случайных чисел, используй себе на php свой на js cвой
они генерируют разные значения и уже попахивает на г-код ибо незачем добавлять каждый раз свой ид. В модулях Joomla для разделения мух от котлет, достаточно было добавляеть ид модуля
$module->id

В js должен быть тот же id что и пхп, во ткак я использую этот id в js
<ul class="slider__list" id="slider__list_<?php echo $id_sfx; ?>">
<?php foreach($last_prod as $curr){ ?>
    <li>
        //...

$("#slider__list_<?php echo $id_sfx  ?>").bxSlider();


т.е. если модуль без id и используется, например, в двух местах на странице, т.е.
$(".slider__list_").bxSlider();

вызывается 2 раза, то при первом вызове слайдер создастся в двух родителях .slider__list_ и и при втором вызове слайдер снова создастся в тех же родителях, а с id каждый раз будет создаватся только в нужном элементе.
Про $module->id не понял, можно поподробнее ?

Vlasenko Fedor 26.01.2014 16:44

var
Цитата:

Сообщение от Danxil
Про $module->id не понял, можно поподробнее

var_dump($module);

Danxil 26.01.2014 16:58

Цитата:

Сообщение от Poznakomlus (Сообщение 294187)
var
var_dump($module);

И как это относится к конфликту при вызове
var elem = $(".slider__list_");

elem .bxSlider();

если elem на странице больше одного ?
Или ты имеешь введу использовать вместо $id_sfx, id модуля ? Тогда при вызове

var elem = $(".slider__list_<?php echo $module->id ?>");

elem .bxSlider();

все равно нужно использовать php в js

Vlasenko Fedor 26.01.2014 17:27

Может подтолкнет, как передать параметры
http://learn.javascript.ru/play/Sgpguc

danik.js 26.01.2014 17:28

Danxil, ты мог бы подтвердить, что код из первого поста корректно отрабатывает в ситуациях когда скрипт bxSlider'а не подключен?
У меня есть сомнения.

Danxil 26.01.2014 17:32

Цитата:

Сообщение от danik.js (Сообщение 294195)
Danxil, ты мог бы подтвердить, что код из первого поста корректно отрабатывает в ситуациях когда скрипт bxSlider'а не подключен?
У меня есть сомнения.



http://danxil.bget.ru/ тут на главной странице этот слайдер, до него bxSlider нигде не подключен, все работает, в консоль сейчас выводится
console.log('bxSlider: ' + $(document).bxSlider);
перед if-ом

Danxil 26.01.2014 17:49

Цитата:

Сообщение от Poznakomlus (Сообщение 294194)
Может подтолкнет, как передать параметры
http://learn.javascript.ru/play/Sgpguc

Точно, через атрибуты вариант, спс !

Danxil 26.01.2014 18:00

Хотя все равно костыльный способ, если будет 10 модулей, то для каждого цикл будет по 10 раз крутится, в итоге 100 итераций, и плюс нужно для каждого элемента проверять создан ли в нем уже слайдер. А так через $id_sfx я напрямую к конкретному элементу обращаюсь ...

Vlasenko Fedor 26.01.2014 18:04

Скажи, а в чем проблема статически прописать эти ид вручную создав для каждого модуля альтернативный макет

danik.js 26.01.2014 18:06

Цитата:

Сообщение от Danxil
все работает

Да уж. Действительно работает. Сначала глазам своим не верил. Перелопатил whatwg документацию... Но потом то я понял что к чему. Гребаная jQuery )) При добавлении скрипта через $().append() jQuery делает синхронный (!!!) аякс-запрос и eval'ит (!!!) содержимое.
Короче сделано в стиле Query: сделано через жуткие костыли, но зато все работает именно так, как этого ждет типичный "jQuery-программист" ... (простите, назвать таких javascript-программистами не могу).

Danxil 26.01.2014 18:28

Цитата:

Сообщение от Poznakomlus (Сообщение 294204)
Скажи, а в чем проблема статически прописать эти ид вручную создав для каждого модуля альтернативный макет


В смысле создать для каждого модуля альтернативный макет, вьюху что ли? Если так то тогда нужно будет при каждом создании модуля прописывать руками ид. Если что, я до этого расширения для джумлы не делал.


Часовой пояс GMT +3, время: 19:07.