Javascript 等待加载高延迟脚本时,在加载DOMContentLoaded之前忽略document.write
我已经尝试了很多不同的方式来表达这个问题给谷歌等,但都不走运。甚至不确定这个问题的标题是否抓住了问题的细微差别。我会试着解释,然后展示这个实验。我希望有人能对发生的事情做出解释 给定:Javascript 等待加载高延迟脚本时,在加载DOMContentLoaded之前忽略document.write,javascript,firefox,google-chrome,domready,Javascript,Firefox,Google Chrome,Domready,我已经尝试了很多不同的方式来表达这个问题给谷歌等,但都不走运。甚至不确定这个问题的标题是否抓住了问题的细微差别。我会试着解释,然后展示这个实验。我希望有人能对发生的事情做出解释 给定: 在正文结尾之前,您有一个脚本(a),它通过编程将脚本元素(使用我首选的技术document.createElement)插入引用远程脚本(B)的文档中 远程脚本B执行任何内容的文档写入(例如“hello,world”) 在正文结尾之前和脚本A之后,您有一个脚本(C),该脚本引用远程脚本,加载该脚本需要一段时间(
- 在正文结尾之前,您有一个脚本(a),它通过编程将脚本元素(使用我首选的技术document.createElement)插入引用远程脚本(B)的文档中
- 远程脚本B执行任何内容的文档写入(例如“hello,world”)
- 在正文结尾之前和脚本A之后,您有一个脚本(C),该脚本引用远程脚本,加载该脚本需要一段时间(例如1s)
- 资料来源:
- 直接试用:
- 瀑布:手动链接[cl.ly/423P2M1D0R0E0K370G]
- 远程脚本:手动链接[thumblemonks.com/js/stackoverflow-script-b.js]
TOP
hello, world
hello again, world
BOTTOM
我得到的输出是:
TOP
hello, world
BOTTOM
你会注意到在我的实验中,我在定义为A和C之间添加了另一个脚本;它表明,如果您动态添加包含document.write的文本(即非远程脚本)的脚本,则a'中的doc.write将起作用
另外,dummy.js和CSS文件来自JSFIDLE。他们不是罪魁祸首;我可以在任何地方重现这个问题
我知道的事情:
- 如果用IMG替换C,则没有问题
- 如果用IFRAME替换C,则没有问题
- 如果将A移到C之后,则没有问题
这是你的问题。脚本被传输为
text/plain
,这对于JavaScript来说不是有效的MIME类型。HTML5不支持从异步加载的脚本写入,这正是因为它的快速性:您无法知道脚本将在加载DOMContentLoaded之前还是之后运行。请参阅和步骤2和步骤3。关键是,如果脚本在加载DOMContentLoaded的竞争中胜出,但如果它在竞争中失败,则将被忽略,这将非常奇怪,并将导致页面有时工作,有时不取决于网络条件。谢谢,Kolink。不过,这只是浏览器的一个功能。在Chrome中,这会执行。我试图让每个人都能看到源代码,但是我已经把这个文件移到了我的一个服务器上,并更新了Fiddle。“你能再试一次吗?谢谢,”鲍里斯·兹巴奇说。伟大的指针。应该从这些规格开始。他们将在浏览webkit源代码时提供帮助。我还没有完成对所有条件的分解,但是为了回应您关于DOM应该做什么的断言,我问:为什么脚本A在脚本C之后移动时执行良好?只有在C之前,这才是一个问题。再说一次,我并不想让document.write工作,我更想知道这里发生了什么。所以,当C在A之前出现时,B(由A加载)实际上需要等待解析完成。这可以解释为什么在这种情况下会忽略破坏性写入。但我想我必须接受这样一个事实:浏览器将执行A(当它位于C之前时),知道解析尚未完成——但仍然将文档视为已关闭。我觉得比赛状态有点奇怪。@Gus我不认为在你的设置中改变a和C的顺序会影响任何事情。你能发布一个链接到一个a和C颠倒的版本吗?还有。document.write仍然无法工作(显然),但您会注意到我们现在进入了交互式readyState;而在前面的示例中,我们仍然处于“加载”状态。你的鼠标指针主要是为我解释的。谢谢。@SKing7插入点由解析器维护。特别是当它看到
时。看见对于非内联脚本,“挂起解析阻止脚本”位将在脚本准备运行时执行相同的操作(请参阅“否则”下的步骤6和8)。但这只适用于解析阻塞脚本,这意味着不使用异步或延迟的脚本。