非常奇怪为什么脚本标签在插入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
第一次运行而不是以下那些
答案 0 :(得分:3)
这里只是澄清,上面的代码可能是一个糟糕的方法,等等。 但问题实际上是指行为以及为什么会发生这种行为。
在过去几分钟玩完之后,我发现只要每个脚本标签都附加到DOM并且有内容,javascript只会运行一次。
例如,您可以在DOM中附加script
标记而不添加任何内容...
那不会激发javascript。但只要您使用innerText
,innerHTML
等向该标记添加内容,它就会立即触发javascript。
很有意思的是,每个脚本标记似乎处理一个标志,每当javascript为该特定标记运行时设置为false
,然后在此之后它赢了不管怎么说,再次开火。
这里有一些有趣的测试:
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会像第一次一样运行。
可以轻松调用以下脚本,它将替换旧脚本标记,并通过简单地提供您希望替换内容的脚本标记来执行新的javascript。
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 :(得分:1)
在脚本执行中的任意点更改<script />
DOM节点的内部文本不会触发重新执行整个脚本,不会。
创建新的脚本标记,或者更好地优化您的方法。你永远不应该发现自己需要注入脚本标签;相反,只需以正常方式执行这些函数调用。
答案 2 :(得分:0)
就是它的样子。您通常不必向现有标记添加新代码;要么创建新标签,要么更好地利用功能和事件。