克隆< script>标签不执行。为什么?
示例:
<script id="hello">
console.log("hello execution count ", window.helloCount++);
</script>
<script id="action">
document.body.appendChild(
document.getElementById('hello').cloneNode(true));
console.log('cloned the script');
</script>
执行后,文档中有两个hello脚本,但只有一个已执行。
http://jsbin.com/zuxoro/1/edit?html,console,output
这是我正在处理的一个更大问题的一部分,所以我知道这是一件蠢事。
答案 0 :(得分:6)
W3C HTML5 specification需要此行为。
每个<script>
元素都有一个名为“已启动”的属性标记。规范说:
最初,脚本元素必须取消设置此标志(脚本块在创建时不会“已经启动”)。 如果在要克隆的元素上设置了脚本元素的克隆步骤,则必须在副本上设置“已启动”标志。
然后,后来:
如果脚本元素被标记为“已经开始”,则用户代理必须在此时中止这些步骤。该脚本未执行。
解决方案不是克隆脚本元素,而是创建使用相同内容填充的全新元素。
答案 1 :(得分:1)
原则上,浏览器在页面上执行<script>
时执行以下操作:
如果在执行以下操作之前未执行脚本<script>
:
<script>
; eval(thatScriptText)
; <script>
DOM节点标记为已执行; 当您克隆节点时,它也会获得内部“已执行”标志,这会阻止脚本进一步执行。
解决方案:如果您希望重新执行脚本,请执行步骤#1和#2。在这种情况下不需要克隆。
答案 2 :(得分:1)
我不知道为什么它不适用于cloneNode
,但您可以通过将innerHTML
复制到新的脚本节点来实现相同的结果。
var clone = document.createElement('script');
clone.innerHTML = document.getElementById('hello').innerHTML;
document.body.appendChild(clone);
console.log('copied the script');
<script>
window.helloCount = 1;
</script>
<script id="hello">
console.log("hello execution count ", window.helloCount++);
</script>
<div>Copied scripts do execute</div>