传统上,加载Javascript文件都是使用<script>标签。javascript
就像下面这样:html
<script type="text/javascript" src="example.js"></script>java
<script>标签很方便,只要加入网页,浏览器就会读取并运行。可是,它存在一些严重的缺陷。api
(1)严格的读取顺序。因为浏览器按照<script>在网页中出现的顺序,读取Javascript文件,而后当即运行,致使在多个文件互相依赖的状况下,依赖性最小的文件必须放在最前面,依赖性最大的文件必须放在最后面,不然代码会报错。数组
(2)性能问题。浏览器采用"同步模式"加载<script>标签,也就是说,页面会"堵塞"(blocking),等待javascript文件加载完成,而后再运行后面的HTML代码。当存在多个<script>标签时,浏览器没法同时读取,必须读取完一个再去读取另外一个,形成读取时间大大延长,页面响应缓慢。浏览器
为了解决这些问题,能够使用DOM方法,动态加载Javascript文件。app
function loadScript(url){异步
var script = document.createElement("script");函数
script.type = "text/javascript";requirejs
script.src = url;
document.body.appendChild(script);
}
这样作的原理是,浏览器即时创造出一个<script>标签,而后"异步"读取Javascript文件。这样不会形成页面堵塞,但会形成另一个问题:这样加载的Javascript文件,不在原始的DOM结构之中,所以在DOM-ready(DOMContentLoaded)事件和window.onload事件中指定的回调函数对它无效。
外部函数库LABjs和RequireJS,能够帮助咱们更有效地管理Javascript加载。
下面根据ScriptJunkie的文章,举一个最简单的例子,来讲明这两个函数库的基本用法。更高级的用法,请参阅它们的文档。
<script src="script1.js"></script>
<script src="script2-a.js"></script>
<script src="script2-b.js"></script>
<script type="text/javascript">
initScript1();
initScript2();
</script>
<script src="script3.js"></script>
<script type="text/javascript">
initScript3();
</script>
上面这段代码,将依次加载4个javascript文件:script1.js、script2-a.js、script2-b.js和script3.js。在加载完前三个文件后,运行两个函数initScript1()和initScript2();加载完第四个文件后,再运行函数initScript3()。
下面,用LABjs对其进行改写:
<script src="LAB.js"></script>
<script type="text/javascript">
$LAB
.script("script1.js").wait()
.script("script2-a.js")
.script("script2-b.js")
.wait(function(){
initScript1();
initScript2();
})
.script("script3.js")
.wait(function(){
initScript3();
});
</script>
首先,$LAB对象替代了<script>标签,而后.script()方法表示加载Javascript文件,不带参数的.wait()方法表示当即运行刚才加载的Javascript文件,带参数的.wait()方法也是当即运行刚才加载的Javascript文件,可是还运行参数中指定的函数。
这里须要注意的是,能够同时运行多条$LAB链,可是它们之间是彻底独立的,不存在次序关系。若是你要确保一个Javascript文件在另外一个文件以后运行,你只能把它们写在同一个链操做之中。只有当某些脚本是彻底无关的时候,你才应该考虑把它们分红不一样的$LAB链,表示它们之间不存在相关关系。
接下来是requireJS的改写:
<script src="require.js"></script>
<script type="text/javascript">
require([
"script1.js",
"script2-a.js",
"script2-b.js",
"script3.js"],
function(){
initScript1();
initScript2();
initScript3();}
);
</script>
require()接受两个参数,第一个数组表示所要加载的Javascript文件,第二个是加载完成后所要运行的回调函数。原生的require()不支持按次序加载,因此四个Javascript文件到底先加载哪一个,没法事前知道,require()只保证这四个文件所有加载完成以后,才会运行所指定的回调函数。
若是按次序加载对你很重要,你能够使用官方提供的order插件。