- defer,只支持IE
- async:
- 创建script,插入到DOM中,加载完毕后callBack
答:
1,什么是异步加载js
- 使js文件脱离html解析的瀑布流加载,从而使js可以并行下载。
2,为什么要异步加载
一般写法将js放在head中,而且默认方式是同步加载,这就会导致在进行js加载的过程中,无法在其加载完成前对后续的内容进行操作,造成页面内阻塞,对用户体验很不友好。
3.如何异步加载
之前我们的写法就是把外部js或js放在body后或内部js放在body结束标签之前,这样会使至少先把一些基本内容加载出来而不会让人等太久,值得注意的是js中一般包含对dom的操作,如果放在body前,就可能出现空白或闪烁,而且js如果放在body内即结束标签之前,则无法获得onload和readystate,需要好好分析。
1. 而比较常用的写法是动态的添加一个script标签,叫做Script DOM Element:
//立即执行函数
(function(){
//创建一个script标签
var scriptTag = document.creatElement("script");
//h4前type必须加上,h5可以不加
scriptTag.type = "text/javascript";
//h5新增的,用这种方法可以不写
scriptTag.async = true;
//你的地址
scriptTag.src = "js地址";
//获取head标签
var headTag = document.getElementsByTagName("head")[0];
//在已有子节点前插入该标签,其实也可以用appendChild
headTag.insertBefore(scriptTag, headTag.firstChild);
})()
但是这个函数又放在哪里呢,我一时间没查到,不过想想应该是放在head中的,毕竟它也是同步加载的。但是这种方法有个问题,它会阻止onload函数的触发,但是我们有很多时候都需要使用这个函数来渲染一些其他东西,所以可以将该函数也放在onload中:
(function(){
//兼容ie,因为ie的window上没有addEventListener
if(window.attachEvent){
window.attachEvent("load", asyncLoad);
//非ie
}else{
window.addEventListener("load", asyncLoad);
}
var asyncLoad = function(){
var scriptTag= document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.async = true;
scriptTag.src ="你的地址";
var headTag= document.getElementsByTagName('head')[0];
headTag.insertBefore(scriptTag, headTag);
}
)();
2. defer
该属性是h5新属性,只有ie可以用,主要可以延迟脚本的执行;
有3点需要注意:
1. defer只适用于外联脚本,如果script标签没有指定src属性,只是内联脚本,不要使用defer
2. 如果有多个声明了defer的脚本,则会按顺序下载和执行
3. defer脚本会在DOMContentLoaded和load事件之前执行
3. script 标签上添加 async 属性
该属性声明外部js的异步加载;
也是3点:
1. 只适用于外联脚本,这一点和defer一致
2. 如果有多个声明了async的脚本,其下载和执行也是异步的,不能确保彼此的先后顺序
3. async会在load事件之前执行,但并不能确保与DOMContentLoaded的执行先后顺序
4. 创建并插入 iframe,让它异步执行 js