скрипт скрипт запускается только первый раз после вставки в DOM - PullRequest
0 голосов
/ 09 июня 2011

Очень любопытно, почему тег script запускается только один раз после вставки в dom.

script = document.createElement('script');
script.type = 'text/javascript'

script
//output: <script type=​"text/​javascript">​</script>​

document.body.appendChild(script);

script.innerHTML = 'console.log("Attempt one")'
//output Attempt one

script.innerHTML = 'console.log("Attempt two")'

script.innerHTML = 'console.log("Attempt three")'

//second and third attempts emit no output

Есть ли способ разрешить запуск других изменений в тексте скрипта?

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

Ответы [ 3 ]

3 голосов
/ 10 июня 2011

Просто чтобы уточнить здесь, что приведенный выше код может быть плохим подходом и т. Д. Но вопрос действительно относится к поведению и почему это происходит.

Проиграв в последние минуты, я мог заметить, что javascript будет запускаться только один раз для каждого тега скрипта, как только он будет добавлен в DOM и имеет содержимое.

Так, например,Вы можете добавить к DOM тег script без какого-либо контента ... который не будет запускать JavaScript.Но как только вы добавите контент к этому тегу с помощью innerText, innerHTML и т. Д., Он сразу же запустит JavaScript.

Интересно отметить, что каждый тег сценария, кажется,обрабатывать флаг , который устанавливается в false каждый раз, когда javascript запускается для этого конкретного тега, после чего он не сработает снова, неважно почему.

Вот некоторые тестыкоторые тоже интересны:

Нормальное поведение

var script = document.createElement('script');

document.body.appendChild(script);

script.innerHTML = 'alert("attemp one")';
// outputs alert
script.innerHTML = 'alert("attemp two")';
// no output

Узел глубокого клонирования

var clone = script.cloneNode(true);
// <script>alert("attemp two")</script>

document.body.replaceChild(clone, script);
// no output

Узел простого клонирования

var clone = script.cloneNode();
// <script></script>

clone.innerHTML = 'alert("attemp two")';

document.body.replaceChild(clone, script);
// no output

Замена для нового тега

var newScript = document.createElement('script');

newScript.innerHTML = 'alert("attempt three")';

document.body.replaceChild(newScript, script);
// output alert

Таким образом, как вы можете видеть, скрипт-тег будет содержать атрибут alreadyExecuted независимо от того, почему, если вы клонируете его, создав точную копию или нет ...

Что делаетЯ думаю, если есть какой-либо способ установить этот флаг в исходное начальное значение вместо создания нового тега script.

Но в худшем случае, если вам действительно нужно это использовать.Нетрудно создать действие, которое получит script, создать новое с теми же атрибутами, если у вас есть, а затем заменить его старым, но с новым содержимым.Javascript будет работать как в первый раз.

Следующий скрипт может быть легко вызван, и он заменит старый тег script на новый и выполнит новый javascript, просто предоставив тег script, который вы хотите заменить содержимым.

function innerScript(element) {

    var newElement = document.createElement('script'),
        attr;

    for (attr = 0; attr < element.attributes.length; attr += 1) {
        newElement.setAttribute(element.attributes[attr].name, element.attributes[attr].value);
    }

    element.parentNode.replaceChild(newElement, element);
    return newElement;

}
1 голос
/ 09 июня 2011

Изменение внутреннего текста узла <script /> DOM в произвольных точках при выполнении сценария не приводит к повторному выполнению всего сценария, нет.

Создание нового тега сценария или, что лучше,уточните свой подход.Вам никогда не придется вставлять теги скрипта;вместо этого просто выполняйте эти вызовы функций обычным способом.

0 голосов
/ 09 июня 2011

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

...