根据http://caniuse.com/script-defer,大多数浏览器都支持script
代码的defer
属性。
我想知道<script defer src="...">
指定的脚本是否在jQuery $(document).ready()
之前或之后执行?主要的现代浏览器(Chrome,Firefox,IE等)是按执行顺序保持一致还是变化?
答案 0 :(得分:15)
基于这个小提琴我不得不说jQuery的$(document).ready()
在用defer
声明的脚本之后执行。我使用Firefox和Chrome进行了测试,两者都具有相同的行为,与脚本的顺序无关。
我猜其他浏览器的行为可能会根据其实现而改变,因此总是不确定。
编辑:事实证明,defer
属性应与外部javascript文件一起使用。我编辑了小提琴来展示这一点,显然也有相同的结果。
此处更新了小提琴:http://jsfiddle.net/RNEZH/15/
答案 1 :(得分:12)
defer属性有一个很好的write-up and analysis。 同时有关如何在HTML5中重新定义defer
的其他信息,请参阅帖子的评论。
我的结论:defer
过于依赖浏览器依赖。因此,请使用jQuery doc ready技术。
换句话说,jQuery的一个重要原因是覆盖浏览器的不一致性。延迟是另一个这样的不一致,对于写得很好的页面应该避免。
答案 2 :(得分:5)
简单地说,script
应该在$(document).ready()
之前执行,无论是否使用defer
以及几乎所有主要浏览器support defer
。
但为了安全起见,我建议您同时使用$(document).ready()
和defer
。
那么为什么defer
?因为它可以帮助页面快速显示(因为外部脚本是并行加载的)并且是Google页面速度工具中非常重要的因素,所以可以在此处找到一个很好的细节http://code.google.com/speed/page-speed/docs/payload.html#DeferLoadingJS
答案 3 :(得分:0)
要推迟内联javscript,可以使用type =“ module”,这样会使$(document).ready()变得多余。
<script type="module">alert('defered inline js')</script>
因为type =“ module”表示延迟脚本将与其他延迟脚本按顺序执行。
请参阅2020年9月我可以使用92%的浏览器支持。 https://caniuse.com/es6-module
答案 4 :(得分:0)
我在 Chrome (88.0.4324.96) 上观察到 jQuery 3.0 之前版本中的竞争条件。我在 Safari 和 Firefox 上都看不到这个。
<body>
<script defer src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script defer src="test.js"></script>
</body>
test.js:
jQuery(document).ready(function ($) {
console.log('jQuery version', $().jquery);
console.log(a);
});
const a = 'OK';
根据我的经验,这在 Cannot access 'a' before initialization
的情况下失败了大约 10%。
一旦我升级到 jQuery 3,我就无法重现。由于这是一个竞争条件,我不能 100% 确定,但对我来说似乎很确定。