只是在这里澄清一下,上面的代码可能是一个不好的方法,等等。
但问题实际上是指行为以及为什么会发生。
在过去的几分钟里玩过之后,我注意到,一旦每个脚本标签都附加到 DOM 并具有内容,javascript 只会为每个脚本标签运行一次。
因此,例如,您可以将script 标记附加到 DOM 中而没有任何内容...
那不会触发javascript。但是,一旦您使用 innerText、innerHTML 等向该标签添加内容...它就会立即触发 javascript。
有趣的是,每个脚本标签似乎都处理一个 flag,每次为该特定标签运行 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;
}