Скрипт скрипт запускается только первый раз после вставки в DOM

Очень любопытно, почему тег 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 ответа

Решение

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

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

Так, например, вы могли бы иметь script тег добавлен в DOM без какого-либо контента... который не будет запускать 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

Так что, как вы можете видеть, тег script будет содержать 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;

}

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

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

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

Другие вопросы по тегам