执行多个document.write时,我注意到他们没有立即修改DOM。第一个document.write立即执行,而其他人对DOM的影响仅在<script>
块的末尾可见。在我测试的Chrome中,它给出了下面的结果。但是在Firefox中,结果与Chrome相同,如果我只是让这段代码运行但不同(见下文),当我一次单步执行代码时。有人可以解释这种行为吗?
<script>
document.write("<script src='test.js'>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script src='test2.js'>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script src='test3.js'>" + "</" + "script>");
console.log(document.scripts.length);
</script>
2
2
2
2
3
4
DOM中的原始脚本数为1(上面列出的内联脚本)。 Chrome在第一个document.write之后更新了DOM,但在此之后等待。那被认为是有缺陷的行为吗?
答案 0 :(得分:0)
问题中的Chrome行为与4.01 specification's model:
完全匹配18.2.4文件的动态修改
加载文档时执行的脚本可能能够动态修改文档的内容。这样做的能力取决于脚本语言本身(例如,某些供应商支持的HTML对象模型中的&#34; document.write&#34; 语句)。 文档的动态修改可以建模如下:
1。在文档加载时,将按顺序评估所有SCRIPT元素。
2。 评估生成SGML CDATA的给定SCRIPT元素中的所有脚本构造。他们的组合生成文本将插入到文档中以代替SCRIPT元素。
3. 生成的CDATA将重新评估。
*(大胆的重点是我的)
Chrome和Firefox可能正在通过(2)&lt; =&gt;(3)在良好形成的未组合生成的文本上执行前瞻,但他们应该表现得好像他们没有根据规范模型评估它们。
因此, Chrome会报告文档中相同数量的脚本,直到父脚本终止,而不是&#34; buggy&#34; 。 (您应该假设您以这种方式添加的所有内容都将被添加/评估,就像它在页面中的下一个脚本元素之前一样,而不是更多。)
由于HTML5正在逐步部署,因此HTML 4.01行为应该是正确的并且是文档所期望的,并且它无法依赖HTML5中的任何说明,无论它是否指定HTML5 DOCTYPE 。因此,在保护4.01中定义的行为时,几乎没有理由查看HTML5规范。 对于4.01中存在的任何功能,每个文档必须与4.01兼容,直到有新的DOCTYPE指示不兼容,而不是请求新功能(如果可用)。
答案 1 :(得分:0)
我无法找到有关该文档的官方文档,但是进行了一些测试我发现浏览器会在脚本的源URL响应后将这些脚本附加到文档中(除了第一个)
document.write("<script src='a.js'>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script src='b.js'>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script src='c.js'>" + "</" + "script>");
console.log(document.scripts.length);
document.onreadystatechange = function() {
if (document.readyState == "complete") {
console.log('Complete: '+document.scripts.length+' scripts found')
}
}
&#13;
在Chrome控制台中,您应该会看到类似这样的内容
但如果他们没有源
,它会立即加载脚本
document.write("<script>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script>" + "</" + "script>");
console.log(document.scripts.length);
&#13;
此外我还注意到,如果只有一个<script>
已定义了源,则在采取响应之前,以下脚本(即使没有源代码)也不会附加到文档
document.write("<script>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script src='a.js'>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script>" + "</" + "script>");
console.log(document.scripts.length);
&#13;
然而,将async添加到<script>
将解决问题
document.write("<script src='a.js' async>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script src='b.js' async>" + "</" + "script>");
console.log(document.scripts.length);
document.write("<script src='c.js' async>" + "</" + "script>");
console.log(document.scripts.length);
document.onreadystatechange = function() {
if (document.readyState == "complete") {
console.log('Complete: '+document.scripts.length+' scripts found')
}
}
&#13;