应用场景:一个70M的 geojson 格式的 js文件 用高德地图把区域渲染出来,加个点击区域弹框展示数据的功能,于是。。。
思路:70M的文件按正常的js同步运行会加载好一会儿,数据都在这个文件里,其他的操作依赖于此文件,考虑将这个70M的js拆分为十几个大小2-5M的js,异步加载依次渲染,不至于让用户等待过久
方案1:script标签,添加async属性,由于这个属性只能加载外部脚本,不能把js代码写在script标签里
async 满足异步 加载结束后会立即执行当前文件
由于项目中其他js文件依赖于 存放 geojson 的js文件,而都设置为异步加载时,小的文件先加载结束这时由于找不到依赖的数据会报错 不满足需求OUT
方案2:script标签 添加defer属性,和html同时加载,html渲染完成后执行 defer满足项目需求会按顺序执行文件,一大缺点 兼容性很差 只有IE满足 OUT
方案3:动态创建script标签
function loadScript(url,callback){ //callback回调函数可以是函数、字符串、数组等
var script = document.createElement('script')
script.type = 'text/javascript'
if(script.readyState){//IE
script.onreadystatechange = function(){ //监听script的状态码的变化
if(script.readyState == 'complete' || 'loaded'){
callback()
//eval(callback) 当callback为字符串(情况1)时,eval可将其当作函数来调用
//obj[callback]() 当callback为字符串(情况2)且所要调用的函数在js文件中是以对象属性的形式存在时
}
}
}else{ //safari、chrome、firefox、opera
script.onload = function(){
callback()
//eval(callback)
//obj[callback]()
}
}
script.src = url //js文件的下载最好放在绑定监听事件之后,以免状态码在绑定监听事件之前已完成变化就不会被监听到
document.head.appendChild(script)
}
// loadScript('index.js',test)
//会报错 test is not defined 因为在传入test的时候,js文件还在函数中未被加载
loadScript('index.js',function(){ //可传入匿名函数 传入时函数内部逻辑不会被解析
test()
})
或
loadScript('index.js','test()') //传入字符串形式(情况1)
或
loadScript('index.js','test') //传入字符串形式(情况2)
十几个文件按此方法依次渲染,岂不是要 回调地狱OUT
方案4:最优解来了 LAB.js 只有6kb, 简洁 灵活
几个简单的案例:
**实例1:**
$LAB
.script("script1.js")
.script("script2.js")
.script("script3.js")
.wait(function(){ // 等待所有script加载完再执行这个代码块
script1Func();
script2Func();
script3Func();
});
**实例2:**
$LAB
.script({ src: "script1.js", type: "text/javascript" })
.script("script2.js")
.script("script3.js")
.wait(function(){ // 等待所有script加载完再执行这个代码块
script1Func();
script2Func();
script3Func();
});
**实例3:**
$LAB
.script("script1.js", "script2.js", "script3.js")
.wait(function(){ // 等待所有script加载完再执行这个代码块
script1Func();
script2Func();
script3Func();
});
**实例4:**
$LAB
.script( [ "script1.js", "script2.js" ], "script3.js")
.wait(function(){ // 等待所有script加载完再执行这个代码块
script1Func();
script2Func();
script3Func();
});
**实例5:**
$LAB
.script("script1.js").wait() // 空的wait()只是确保script1在其他代码之前被执行
.script("script2.js") // script2 和 script3 依赖于 script1
.script("script3.js").wait() // 但是script2 和 script3 并不互相依赖,可以并行下载
.script("script4.js") // script4 依赖于 script1, script2 及 script3
.wait(function(){script4Func();});
**实例6:**
$LAB
.script("script1.js") // script1, script2, and script3 之间没有依赖关系,
.script("script2.js") // 所以可以任意顺序执行
.script("script3.js")
.wait(function(){ // 如果需要,这里当然可以执行javascript函数
alert("Scripts 1-3 are loaded!");
})
.script("script4.js") // 依赖于 script1, script2 及 script3
.wait(function(){script4Func();});
**实例7:**
$LAB
.setOptions({AlwaysPreserveOrder:true}) // 设置每个脚本之间等待
.script("script1.js") // script1, script2, script3, script4 互相依赖
.script("script2.js") // 并且并行下载后循序执行
.script("script3.js")
.script("script4.js")
.wait(function(){script4Func();});
**实例8:**
$LAB
.script(function(){
// `_is_IE`的值ie为true ,非ie为false
if (_is_IE) {
return "ie.js"; // 如果是ie则这个js会被加载
}
else {
return null; //如果不是ie这个代码就会被略过
}
})
.script("script1.js")
.wait();