我试图弄清楚我继承的一些代码存在问题。
我有一个带
的HTML页面<script type="text/javascript" src="file1.js" defer="defer"></script>
<script type="text/javascript" src="file2.js" defer="defer"></script>
</body>
</html>
file1.js有
FOO = {
init : function () {
var bar = BAR;
}
}
$(document).ready(FOO.init);
file2.js有
var BAR = {
}
由于元素的延迟属性,可以安全地假设.ready()
调用FOO.init()
时BAR
可能仍然未定义b / c代码由于延迟执行,file2.js
尚未执行?
这将匹配我试图追踪的错误(仅在IE中偶尔发生),但我真的想在我处理解决方案之前理解为什么发生这种情况。我不知道为什么原始的开发人员使用defer
,除了一个神秘的推荐,“他必须”这样做。
答案 0 :(得分:2)
Defer应该将脚本添加到页面完全加载后处理的队列中。根据规范,延迟脚本应按照它们进入页面的顺序添加到队列中。
然而,不同的浏览器对订单的处理方式略有不同。 IE似乎按照完成加载的顺序运行延迟脚本,而不是它们在页面上发生的顺序。所以你偶尔会看到这个错误,因为有时它会以正确的顺序加载它们,有时却不会。
请参阅hacks.mozilla.com上的this post以获取更详尽的解释以及不同浏览器如何处理延迟队列排序的示例。
答案 1 :(得分:1)
Deffering优先考虑何时解释脚本的浏览器,在某些最佳条件下,例如使用chrome,在加载页面时下载脚本然后进行解析和解释。如果像上面那样使用延迟,则永远无法确定首先加载哪个脚本或解释完成。
BAR
可能在一个页面加载时未定义,并在重新加载(缓存)上定义,或者第二个脚本首先加载。
要测试此操作,请尝试更改其中一个脚本以强制进行新的下载和解释,并查看存在的竞争条件。