动态加载JS函数
一般性的,当我们需要加载js文件的时候都会使用script标签来实现,类似于如下代码:
<script type="text/javascript" src="example.js"></script>
但是直接使用script标签来加载js文件会有如下一些缺点:
- 严格的读取顺序。由于浏览器按照<script>在网页中出现的顺序,读取Javascript文件,然后立即运行,导致在多个文件互相依赖的情况下,依赖性最小的文件必须放在最前面,依赖性最大的文件必须放在最后面,否则代码会报错。
- 性能问题。浏览器采用"同步模式"加载<script>标签,也就是说,页面会"堵塞"(blocking),等待javascript文件加载完成,然后再运行后面的HTML代码。当存在多个<script>标签时,浏览器无法同时读取,必须读取完一个再去读取另一个,造成读取时间大大延长,页面响应缓慢。
这个时候我们就会想到去动态加载JS,动态加载js的实现方法类似于如下代码
/* *@desc:动态添加script *@param src:加载的js文件的地址 *@param callback:js文件加载完成之后需要调用的回调函数 *@demo: addDynamicStyle('http://webresource.c-ctrip.com/code/cquery/LABjs/LAB.js', function () { alert('携程服务器上的lab.js加载完成') }); */ function addDynamicJS(src, callback) { var script = document.createElement("script"); script.setAttribute("type", "text/javascript"); script.src = src[i]; script.charset = 'gb2312'; document.body.appendChild(script); if (callback != undefined) { script.onload = function () { callback(); } } }
这样不会造成页面堵塞,但会造成另外一个问题:这样加载的Javascript文件,不在原始的DOM结构之中,因此在DOM-ready(DOMContentLoaded)事件和window.onload事件中指定的回调函数对它无效。
这个时候我们就会想到用一些外部函数库来有效的管理JS加载问题。
下面进入正题说说LAB.js
LAB.js
如果我们使用传统的方法来加载js的话,写的代码一般会如下方代码所示风格。
<script src="aaa.js"></script> <script src="bbb-a.js"></script> <script src="bbb-b.js"></script> <script type="text/javascript"> initAaa(); initBbb(); </script> <script src="ccc.js"></script> <script type="text/javascript"> initCcc(); </script>
如果我们使用LAB.js的话,要实现上述代码功能,则使用如下方式
<!--先加载lab.js库--> <script src="http://webresource.c-ctrip.com/code/cquery/LABjs/LAB.js"></script> <script type="text/javascript"> $LAB .script("aaa.js").wait()//不带参数的.wait()方法表示立即运行刚才加载的Javascript文件 .script("bbb-a.js") .script("bbb-b.js")//依次加载aaa.js bbb-a.js bbb-b.js 然后执行initAaa initBbb .wait(function () {//带参数的.wait()方法也是立即运行刚才加载的Javascript文件,但是还运行参数中指定的函数。 initAaa(); initBbb(); }) .script("ccc.js")//再加载ccc.js 加载完成ccc.js之后执行initCcc方法 .wait(function () { initCcc(); }); </script>
可以同时运行多条$LAB链,但是它们之间是完全独立的,不存在次序关系。如果你要确保一个Javascript文件在另一个文件之后运行,你只能把它们写在同一个链操作之中。只有当某些脚本是完全无关的时候,你才应该考虑把它们分成不同的$LAB链,表示它们之间不存在相关关系。
一般性的使用示例
$LAB .script("script1.js") // script1, script2, and script3 相互不依赖, 可以按照任意的顺序执行 .script("script2.js") .script("script3.js") .wait(function(){ alert("Scripts 1-3 are loaded!"); }) .script("script4.js") //必须等待script1.js,script2.js,script3.js执行完毕之后才能执行 .wait(function(){script4Func();});
$LAB .script("script.js") .script({ src: "script1.js", type: "text/javascript" }) .script(["script1.js", "script2.js", "script3.js"]) .script(function(){ // assuming `_is_IE` defined by host page as true in IE and false in other browsers if (_is_IE) { return "ie.js"; // only if in IE, this script will be loaded } else { return null; // if not in IE, this script call will effectively be ignored } })
在控制台看LAB.js的加载信息
如果你想调试或者说在控制台看各个js加载信息的话,可以使用$LAB.setGlobalDefaults 方法,具体使用请看代码示例。
<!--先加载携程的LAB库 lab.js在网上也可以下载--> <script type="text/javascript" src="http://webresource.c-ctrip.com/code/cquery/LABjs/LAB.js" charset="gb2312"></script> <script type="text/javascript"> $LAB.setGlobalDefaults({ Debug: true }) //打开调试 $LAB //第一个执行链 .script('http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js') .script('http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js') //第二个执行链 .wait(function () { //console.log(window.$) //console.log(window._) }) //第三个执行链 .script('http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/js/bootstrap.min.js') .script('http://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.pack.js') //第四个执行链 .wait(function () { // console.log(plugin1Function) // console.log(plugin2Function) }) //第五个执行链 .script('js/aaa.js') .script('js/bbb.js') //第六个执行链 .wait(function () { // console.log(module1Function) // console.log(module2Function) }) </script>
这个时候打开控制台,看信息,如下图所示:
我相信你看到这儿肯定会为Lab.js的调试功能惊叹不已。事实上Lab.js确实是挺强大的,我也只是了解它的一些浅显的功能。先记下来,拿来分享一下同时也为了以后方便自己。