我尝试了许多不同的方法来向谷歌等人提出这个问题,但没有运气。甚至不确定这个问题的标题是否能抓住问题的细微差别。我将尝试解释然后展示实验。我希望有人能够指出发生了什么的一些解释。
鉴于:
- 在 BODY 结束之前,您有一个脚本 (A),它以编程方式将脚本元素(使用我的首选技术 document.createElement)插入到引用远程脚本 (B) 的文档中
- 远程脚本 B 执行任何内容的 document.write(例如“hello, world”)
- 在 BODY 结束之前和脚本 A 之后,您有一个脚本 (C),它引用了一个需要一段时间才能加载的远程脚本(例如 1 秒)
将会发生的是 A 执行,将 B 插入到文档中并开始下载资源。当 B 正在下载时,由于延迟,C 将执行并等待。在 C 等待期间,B 被下载并执行;我们还没有点击 DOMContentLoaded;document.readyState 仍在“加载”中。来自 B 的 document.write 被忽略;狼吞虎咽,好像我们是后 DOMContentLoaded。C 然后完成下载并执行。
实验:
- 来源:http: //jsfiddle.net/jaknowlden/pwHG8/
- 直接试用:http: //jsfiddle.net/jaknowlden/pwHG8/show/
- 瀑布:手动链接[cl.ly/423P2M1d0r0e0k3h370g]
- 远程脚本:手动链接[thumblemonks.com/js/stackoverflow-script-b.js]
我正在使用 Cuzillion 来制造延迟。如果您查看瀑布图,您还会看到 console.log 消息,它显示所有内容都在 DOM 达到“交互式”就绪状态(即 DOMContentLoaded)之前执行。
我期望在浏览器中的输出是:
TOP
hello, world
hello again, world
BOTTOM
我得到的输出是:
TOP
hello, world
BOTTOM
您会注意到,在我的实验中,我在定义为 A 和 C 之间添加了另一个脚本。我想将其称为 A';它表明,如果您动态添加包含 document.write 的文本(即不是远程脚本)的脚本,则 A' 中的 doc.write 将起作用。
此外,dummy.js 和 CSS 文件来自 JSFiddle。他们不是罪魁祸首;我可以在任何地方重现这个问题。
我知道的事情:
- 如果您将 C 替换为 IMG,则没有问题
- 如果将 C 替换为 IFRAME,则没有问题
- 如果在 C 之后移动 A,则没有问题
现在:
也许这有一个完全正当的理由。必须有,因为我测试过的所有浏览器似乎都以大致相同的方式运行。我想知道为什么?欢迎任何解释、提示和/或指针。甚至像“它在规范中,愚蠢的:)”这样的提示我的脸皮很厚;我应付得来。
免责声明:我讨厌 document.write。我的意图不是以任何方式支持或支持它的使用。然而,考虑到我工作的性质,我现在必须解决它,这种奇怪的事情突然出现在我身上。因此,我想避免“你不应该使用 document.write”这样的评论,因为我已经相信了:)