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

Gus*_*Gus 3 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
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

TOP
hello, world
BOTTOM
Run Code Online (Sandbox Code Playgroud)

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

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

我知道的事情:

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

现在:

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

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

Bor*_*sky 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 step 2 and http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#execute-the -script-block第3步.关键是如果脚本击败DOMContentLoaded,但如果失去竞争就被忽略,那么写入工作会很奇怪,会导致页面有时工作,有时不依赖于网络条件.