【问题标题】:Why script elements created through DOMParser do not execute?为什么通过 DOMParser 创建的脚本元素不执行?
【发布时间】:2015-03-22 15:55:24
【问题描述】:

我在 Ajax 中加载 HTML,用 DOMParser 解析它并将文档正文的所有 childNodes 放入文档片段中。

当我将片段添加到当前文档的正文中时,<script> 标签不会被执行。

我摆弄了一下,发现如果我用新的动态创建的脚本标签替换它们,它们就会被正确执行。

我想知道为什么?

例如

var html = "Some html with a script <script>alert('test');</script>";

var frag = parsePartialHtml(html);


fixScriptsSoTheyAreExecuted(frag);


document.body.appendChild(frag);


function fixScriptsSoTheyAreExecuted(el) {
  var scripts = el.querySelectorAll('script'),
      script, fixedScript, i, len;

  for (i = 0, len = scripts.length; i < len; i++) {
    script = scripts[i];

    fixedScript = document.createElement('script');
    fixedScript.type = script.type;
    if (script.innerHTML) fixedScript.innerHTML = script.innerHTML;
    else fixedScript.src = script.src;
    fixedScript.async = false;

    script.parentNode.replaceChild(fixedScript, script);
  }
}


function parsePartialHtml(html) {
  var doc = new DOMParser().parseFromString(html, 'text/html'),
      frag = document.createDocumentFragment(),
      childNodes = doc.body.childNodes;

  while (childNodes.length) frag.appendChild(childNodes[0]);

  return frag;
}

不调用fixScriptsSoTheyAreExecuted,什么都不会执行。

我发现难以理解的另一点是,如果我尝试简单地克隆现有脚本节点以使用 cloneNode 创建新的脚本节点,它不起作用,这表明最初创建的脚本标签由DOMParser 携带阻止它们被执行的状态。

【问题讨论】:

  • @Nit,这根本不是真的。肯定会执行动态添加的脚本。我在问为什么通过DOMParser 对象动态创建的脚本不像使用document.createElement 创建的脚本那样执行。
  • 还值得注意的是,此代码也仅在您创建新的fragment 并移动节点时才有效。如果您只是尝试将已解析的节点直接附加到主文档,无论是否使用 fix 方法,脚本都不会执行

标签: javascript html dynamic-script-loading


【解决方案1】:

DOM Parsing and Serialization 规范中对此进行了解释:

parseFromString

parseFromString(str, type) 方法必须运行这些步骤, 取决于类型:

【讨论】:

  • 谢谢,我应该考虑看看规范;)
猜你喜欢
  • 2016-09-11
  • 1970-01-01
  • 2013-08-25
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 2021-12-30
  • 2013-09-13
  • 2014-06-11
相关资源
最近更新 更多