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