在等待加载高延迟脚本时,在DOMContentLoaded之前忽略document.write

时间:2012-03-20 21:56:52

标签: javascript firefox google-chrome domready

我尝试过很多不同的方法来对google等人提出这个问题并没有运气。甚至不确定这个问题的标题是否抓住了问题的细微差别。我会尝试解释然后展示实验。我希望有人能够指出对正在发生的事情的一些解释。

假设:

  • 在BODY结束之前,您有一个脚本(A)以编程方式将脚本元素(使用我的首选技术document.createElement)插入到引用远程脚本(B)的文档中
  • remote-script B执行任何内容的document.write(例如“hello,world”)
  • 在BODY结束之前和脚本A之后你有一个脚本(C)引用一个需要一段时间加载的远程脚本(例如1s)

A会执行,将B插入文档并开始下载资源。当B正在下载时,由于延迟,C将执行并等待。当C在等待时,B被下载并执行;我们还没有点击DOMContentLoaded; document.readyState仍在“加载”。来自B的document.write被忽略;狼吞虎咽,好像我们是post-DOMContentLoaded。 C然后完成下载并执行。

实验:

我正在使用Cuzillion来制造延迟。如果你看看瀑布图像,你还会看到console.log消息,它显示在DOM命中“interactive”readyState(即DOMContentLoaded)之前所有内容都已执行。

我期望在浏览器中输出的内容是:

TOP
hello, world
hello again, world
BOTTOM

我得到的输出是:

TOP
hello, world
BOTTOM

你会在我的实验中注意到我在我们定义为A和C之间添加了另一个脚本。请调用此A'我想;它表明,如果你动态添加一个包含document.write的文本(即不是远程脚本)的脚本,A'中的doc.write将会起作用。

此外,dummy.js和CSS文件来自JSFiddle。他们不是罪魁祸首;我可以在任何地方重新创建这个问题。

我知道的事情:

  • 如果用IMG替换C,则没有问题
  • 如果用IFRAME替换C,则没有问题
  • 如果你在C之后移动A,则没有问题

立即

也许有一个完全正确的理由。必须有,因为我测试的所有浏览器似乎都以大致相同的方式运行。我想知道的是为什么?欢迎任何解释,提示和/或指示。甚至提示“这是规格,dumby :)”我的皮肤很厚;我可以处理它。

免责声明:我厌恶document.write。我的意图不是以任何方式支持或加强其使用。然而,鉴于我的工作性质,我现在必须解决它,这种奇怪的现象在我身上浮现。因此,我想避免沿着“你不应该使用document.write”这句话的评论,因为这,我已经相信:)

2 个答案:

答案 0 :(得分:5)

HTML5不支持从异步加载的脚本执行document.write,正是因为它非常简洁:您无法知道您的脚本是在DOMContentLoaded之前还是之后运行。请参阅http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#ignore-destructive-writes-counterhttp://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-write第2步和http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#execute-the-script-block第3步。重点是如果脚本击败DOMContentLoaded但是如果它失去了比赛则会被忽略奇怪的,会导致页面有时工作,有时不依赖于网络条件。

答案 1 :(得分:0)

  

SEC7112:https://raw.github.com/gist/2141272/1a6bf0111ce10d55e628e3736a9d381d82e8a780/external-with-docwrite.js的脚本由于mime类型不匹配而被阻止

这是你的问题。该脚本将作为text/plain传输,这不是JavaScript的有效MIME类型。