博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HTML5学习笔记(二十三):DOM应用之动态加载脚本
阅读量:6265 次
发布时间:2019-06-22

本文共 2477 字,大约阅读时间需要 8 分钟。

同步加载和执行JS的情况

在HTML页面的</body>表情之前添加的所有<script>标签,无论是直接嵌入JS代码还是引入外部js代码都是同步执行的,这里的同步执行指的是在加载好和执行完JS代码之前整个浏览器的界面都是阻塞的。

静态加载时

内嵌代码和引入js代码都是同步加载。

动态加载时

通过document.write('<script src="xxx.js"></script>');的方式加入的代码也是同步加载的,但是要注意一点,这里开始加载和解析xxx.js是在执行完成当前的<script>标签之后,所以下面的代码会报错(我们假设test.js中创建了全局的p对象,且该对象存在sayHi的方法):

1 ');4     console.log(p.sayHi());5 

根据我们说的开始加载和解析xxx.js是在执行完成当前的<script>标签之后,可以把上面的代码转换如下:

1 5 

这样必然会出错,如下则可以正常执行:

1 ');4 5 

document.write方式同步加载外部js文件无论是内嵌的写法还是写在外部js文件中,效果都是一样的,都会同步加载和执行。

异步加载和执行JS的情况

静态加载时

对于内嵌的JS代码只能同步执行,对于通过<script>标签引入的外部js文件,可以通过设定defer和async两个属性改变为异步加载执行。

defer

代码如下:<script src="xxx.js" defer></script>,该属性在HTML4.01引入,告诉浏览器立即下载该脚本(下载期间不阻塞页面),但是等待遇到</html>标签之后再执行,同时执行顺序按照标签出现顺序进行执行。该脚本的执行一定会在页面的load事件之前。

async

代码如下:<script src="xxx.js" async></script>,该属性在HTML5引入,告诉浏览器立即下载该脚本(下载期间不阻塞页面),但是执行脚本时不能保证按照标签出现顺序执行。该脚本的执行一定会在页面的load事件之前。

最佳实践

由于浏览器的支持不同,所以最好的方法仍然是将<script src="xxx.js"></script>脚本放在页面的最下方引入。

动态加载时

如果我们希望在页面任意时刻动态异步加载js文件,可以通过使用DOM元素创建方法来实现:

1 var script = document.createElement("script");2 script.type = "text/javascript";3 script.src = "xxx.js";4 document.getElementsByTagName("head")[0].appendChild(script);

当script元素被添加到页面之后便开始下载脚本文件。该技术的优点是:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。当script文件下载完成后,返回的代码通常被立即执行(除了FF和Opera,它们将等待此前的所有动态脚本节点执行完毕。)

唯一的问题是我们需要知道动态加载的脚本何时完成加载并可以使用,FF, Opera, Chrome和Safari3+会在节点接收完成后发出一个load事件;IE则是发出一个readystatechange事件,<script>元素有一个readyState属性,它的值随着下载过程而改变。readyState有5种取值:uninitialized(默认状态),loading(下载开始),loaded(下载完成),interactive(下载完成但尚不可用),complete(所有数据已准备好)。

最终的代码如下:

1 function loadScript(url, callback){ 2     var script = document.createElement("script"); 3     script.type = "text/javascript"; 4     if (script.readyState) { // IE 5         script.onreadystatechange = function() { 6             if (script.readyState == "loaded" || script.readyState == "complete") { 7                 script.onreadystatechange = null; 8                 callback(); 9             }10         };11     } else { // FF, Chrome, Opera, ...12         script.onload = function() {13             callback();14         };15     }16     script.src = url;17     document.getElementsByTagName("head")[0].appendChild(script);18 }

如果要加载多个文件,并且要保证顺序,则可以采用将上述函数串联的方式实现。

1 loadScript("../scripts/test1.js", function(){2     loadScript("../scripts/test2.js", function(){3         loadScript("../scripts/test3.js", function(){4             test3.print("hi, i'm abc.");5         })6     });7 });

如果觉得这种嵌入的写法太不爽,也可以稍作修改改为Promise的写法。

转载地址:http://rfdpa.baihongyu.com/

你可能感兴趣的文章
jQuery Ajax 实例 全解析
查看>>
博客装扮3-博客园界面装扮优化教程
查看>>
STM32CubeMX的串口配置,以及驱动代码
查看>>
组合数学 + STL --- 利用STL生成全排列
查看>>
Notepad++配置c/c++环境
查看>>
PHP——获取上传文件的后缀名
查看>>
全面理解HTTP协议
查看>>
lhgdialog弹出窗口控件 v4.1.0使用总结
查看>>
linux 中nvme 的中断申请及处理
查看>>
linux的nvme驱动参数调优
查看>>
unity编辑器之自动提示订外卖
查看>>
完整的项目管理流程(软件开发)
查看>>
PHP命名空间和自动加载初探
查看>>
跳台阶问题 【微软面试100题 第二十七题】
查看>>
C# 中的常用正则表达式总结(3)
查看>>
数据解析2:JSON解析(2)
查看>>
OpenJudge/Poj 1661 帮助 Jimmy
查看>>
C语言数据转换
查看>>
hdu2018
查看>>
使用CRF做命名实体识别(三)
查看>>