IE9注入脚本标签的执行顺序是否已知有解决方法?

3

我相信我并没有完全理解这个问题,但是看起来我们在我的项目上看到了IE9上的奇怪行为,与通过调用document.write注入的JavaScript的乱序执行有关,例如:

document.write('<scr'+'ipt type="text/javascript" src="'+file1+'"></src'+'ipt>');
document.write('<scr'+'ipt type="text/javascript" src="'+file2+'"></src'+'ipt>');
document.write('<scr'+'ipt type="text/javascript" src="'+file3+'"></src'+'ipt>');

我的有限谷歌研究表明,IE9将以不同的顺序执行通过这种方式注入的脚本,与其他浏览器(特别是Firefox和Chrome)不同。有没有更好的方法来实现我们在这里所追求的目标,可以确保所有浏览器都按照相同的执行顺序执行?

我收回之前说的话:我们并不真正关心所有浏览器,只关心Chrome和IE9。


(自言自语)我在想,在IE9中使用document.write()将脚本插入DOM是否是非阻塞操作? - Russ Cam
1
(也在自言自语):是否可以为每个注入的标签添加一个“defer”属性?我不知道它会产生什么影响,但如果脚本当前按照它们完成下载的顺序进行评估(即最小/最快主机优先),而不是按照它们声明的顺序进行评估,那么添加“defer”可能会强制它们堆叠。也许。 - Flambino
我相信它是的。这是一种广泛接受的解决非阻塞JavaScript调用的方案。 - Robin Winslow
@Flambino:我不太了解defer属性,但我确实已经尝试过了,似乎并没有解决问题。 - Dan Tao
4个回答

5
我猜您可以链式调用一个元素的onload事件来启动另一个元素的加载:
var newJS= document.createElement('script');
newJS.onload=function() {alert("done")} //or call next load function
newJS.src="..."
document.body.appendChild(newJS)

那就是“JavaScript 的方式” :) - Ziggy

5
使用脚本加载器(比如我写的一个:LABjs),它可以规范各种浏览器加载的不同怪癖。而且还有个好处:它不使用那个可怕的document.write()。LABjs可以让你异步(并行)地加载所有脚本,但要确保它们按正确的顺序执行。听起来基本上就是你想要的东西。

2
因此,使用这种方式编写脚本标记的优点在于它们被异步加载。我不知道有关浏览器如何执行此操作的细微差别,但我认为它们在下载时被执行,没有特定的顺序。类似于HTML5 async 属性的行为。
还有另一个HTML5 属性defer,它使得脚本按顺序执行,但是以非阻塞方式执行。您可以尝试将其添加到生成的<script>标记中。IE9 部分支持它

2
一个更好的关于 asyncdefer 的资源:http://www.w3.org/TR/html5/scripting-1.html - Robin Winslow
1
document.write 是同步的,而不是异步的。 - user1385191
document.write是同步的。将<script>标签写入文档(使用document.write或其他方法)会导致所引用的JavaScript文件异步加载。http://friendlybit.com/js/lazy-loading-asyncronous-javascript/ - Robin Winslow
不,使用document.write编写的脚本仍然是同步的。为什么会因为指定了脚本而使函数表现出任何不同呢?此外,在那篇文章中甚至没有提到document.write(除了在评论中略微提到)。请考虑这个演示:http://jsbin.com/opetat/edit#source - user1385191

0

我写了一个小脚本,专门用于这个目的:

https://github.com/mudroljub/js-async-loader

简而言之,它异步加载所有脚本,然后按顺序执行它们。它看起来像这样:
for (var lib in libs) {
    loadAsync(lib);
}

你不需要使用 document.write();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接