【发布时间】: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