繁体   English   中英

为什么不克隆节点<script> tags execute?

[英]Why don't cloneNode <script> tags execute?

克隆的<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

这是我正在研究的一个更大问题的一部分,所以我知道这是一件愚蠢的事情。

W3C HTML5规范要求此行为。

每个<script>元素都有一个名为“ 已启动 ”的属性标志。 规范说:

最初,脚本元素必须取消设置此标志(脚本块在创建时不会“已经启动”)。 如果在要克隆的元素上设置了脚本元素的克隆步骤,则必须在副本上设置“已启动”标志。

然后,后来:

如果脚本元素被标记为“已经开始”,则用户代理必须在此时中止这些步骤。 该脚本未执行。

解决方案不是克隆脚本元素,而是创建使用相同内容填充的全新元素。

原则上,浏览器在页面上执行<script>时会执行以下操作:

如果在执行以下操作之前未执行脚本<script>

  1. <script>获取文本;
  2. 调用eval(thatScriptText) ;
  3. <script> DOM节点标记为已执行;

克隆节点时,它也会获得内部“已执行”标志,这会阻止脚本进一步执行。

解决方案:如果您希望重新执行脚本,请执行步骤#1和#2。 在这种情况下不需要克隆。

我不知道为什么它不能用于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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM