在学习JavaScript的一些总结和经验,供大家参考和学习,同时也欢迎大家参与讨论。
异步加载
延迟脚本defer
- 脚本会被延迟到整个页面都解析完毕(即DomTree构建完,并不代表整个页面加载完),通知浏览器该脚本将在文档完成解析后,触发 DOMContentLoaded 事件前执行。
- defer属性只适用于外部脚本文件
- IE9以下版本才能用
1 | <script type="text/javascript" defer="defer" src="example.js"></script> |
异步脚本async
- 只能加载外部脚本文件
- W3C标准方法,大多数浏览器支持
- 标记有async属性的脚本并不保证按照指定他们的先后顺序执行。
1 | <script type="text/javascript" async="async" src="example.js"></script> |
动态加载脚本
1 | var script = document.createElement('script'); |
竟然说添加了这段document.body.appendChild(script);就是执行test.js了,那我们在test.js文件中添加这段代码:function test(){alert("hello")};并在下面原来的代码添加调用test()
1 | var script = document.createElement('script'); |
按照我们正常的理解,这样页面应该会弹出hello,但是很遗憾,控制台弹出了这样的错误:
Uncaught ReferenceError: test is not defined,test根本就没定义?这是怎么回事?
解释:我们知道,程序执行是微妙(ms)级别的;非常快的,当程序读到test()的时候,上面的script.src中的test.js文件还没加载完,所以执行不了test()函数;所以出现未定义的错误。
问题:那么,有没有一种办法,可以等到test.js文件加载完了,才执行之后的代码?
onload事件
整个HTML页面解析完(图像等加载完)才执行
1 | var script = document.createElement('script'); |
IE上有一个状态码,script.readyState,功能与script.onload类似;
script.readyState = “loading”;最开始的值。
script.readyState = “complete”;或者是“loaded”表示加载完成
我们加一个监听这个readyState属性的事件onreadystatechange,它依赖于readyState的变化,一旦readyState的值变化,就会触发onreadystatechange事件。
1 | var script = document.createElement('script'); |
我们要知道,一旦readyState变化,就会触发onreadystatechange事件
那么有没有出现一种情况:就是script.src 瞬间就下载完,也就是瞬间到达”complete”或”loaded”阶段,那么onreadystatechange事件就不会被触发,那么在IE上就不好使了,所以我们改善一下代码,把script.scr = url这段移到if循环下面,顺便封装成loadScript函数。
1 | function loadScript(url, callback){ |
于是我们高高兴兴的执行一下代码,心想着能够成功,哦吼完蛋,报错了ReferenceError: test is not defined,为什么会出现未定义的错误呢?
解释:因为代码在执行的时候,它的执行顺序是解析一下function loadScript(){}函数,它根本不会去执行loadScript里面的代码,然后在执行loadScript('test.js',test);的时候才会触发loadScript函数里面代码的执行,也就是当loadScript('test.js',test);在传参的时候发生在test.js文件加载之前,所以它根本不知道test是什么?
我们就加一个匿名函数:它也是一个函数的引用,它也不会去执行它里面的代码只是先解析。
1 | loadScript('test.js',function(){ |
我们把test.js写成json对象的一个形式,我们这样写的优点就是如果我们在加载一个库时,我们只需要加载里面的某个方法,我们就可以采用这个形式进行按需加载,比较灵活。
test.js文件:
1 | var test = { |
1 | function loadScript(url, callback){ |
文章标题: 异步加载的三个方法
文章作者: 王奕聪,QQ:1301842163
许可协议:
©署名-非商用-相同方式共享 4.0
