手记

JavaScript优化篇5-Dynamic Script Elements 动态脚本元素

Dynamic Script Elements 动态脚本元素

文档对象模型(DOM)允许你使用JavaScript 动态创建HTML 的几乎全部文档内容。其根本在于,<script>元素与页面其他元素没有什么不同:引用变量可以通过DOM 进行检索,可以从文档中移动、删除,也可以被创建。一个新的<script>元素可以非常容易地通过标准DOM 函数创建:

var script = document.createElement (“script”);

script.type = “text/javascript”;

script.src = “file1.js”;

document.getElementsByTagName_r(“head”)[0].appendChild(script);

新的<script>元素加载file1.js 源文件。此文件当元素添加到页面之后立刻开始下载。此技术的重点在于:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。你甚至可以将这些代码放在<head>部分而不会对其余部分的页面代码造成影响(除了用于下载文件的HTTP 连接)。

当文件使用动态脚本节点下载时,返回的代码通常立即执行(除了Firefox 和Opera,他们将等待此前的所有动态脚本节点执行完毕)。当脚本是“自运行”类型时这一机制运行正常,但是如果脚本只包含供页面其他脚本调用调用的接口,则会带来问题。这种情况下,你需要跟踪脚本下载完成并准备妥善的情况。可

以使用动态<script>节点发出事件得到相关信息。

Firefox, Opera, Chorme 和Safari 3+会在<script>节点接收完成之后发出一个load 事件。你可以监听这一事件,以得到脚本准备好的通知:

var script = document.createElement (“script”)

script.type = “text/javascript”;

//Firefox, Opera, Chrome, Safari 3+

script.onload = function(){

alert(“Script loaded!”);

};

script.src = “file1.js”;

document.getElementsByTagName_r(“head”)[0].appendChild(script);

Internet Explorer 支持另一种实现方式,它发出一个readystatechange 事件。<script>元素有一个readyState

属性,它的值随着下载外部文件的过程而改变。readyState 有五种取值:

“uninitialized” The default state

“uninitialized”默认状态

“loading” Download has begun

“loading”下载开始

“loaded” Download has completed

“loaded”下载完成

“interactive” Data is completely downloaded but isn’t fully available

“interactive”下载完成但尚不可用

“complete” All data is ready to be used

“complete”所有数据已经准备好

微软文档上说,在<script>元素的生命周期中,readyState 的这些取值不一定全部出现,但并没有指出哪些取值总会被用到。实践中,我们最感兴趣的是“loaded”和“complete”状态。Internet Explorer 对这两个readyState 值所表示的最终状态并不一致,有时<script>元素会得到“loader”却从不出现“complete”,但另外

一些情况下出现“complete”而用不到“loaded”。最安全的办法就是在readystatechange 事件中检查这两种状态,并且当其中一种状态出现时,删除readystatechange 事件句柄(保证事件不会被处理两次):

var script = document.createElement (“script”)

script.type = “text/javascript”;

//Internet Explorer

script.onreadystatechange = function(){

if (script.readyState == “loaded” || script.readyState == “complete”){

script.onreadystatechange = null;

alert(“Script loaded.”);

}

};

script.src = “file1.js”;

document.getElementsByTagName_r(“head”)[0].appendChild(script);

大多数情况下,你希望调用一个函数就可以实现JavaScript 文件的动态加载。下面的函数封装了标准实

现和IE 实现所需的功能:

function loadScript(url, callback){

var script = document.createElement (“script”)

script.type = “text/javascript”;

if (script.readyState){ //IE

script.onreadystatechange = function(){

if (script.readyState == “loaded” || script.readyState == “complete”){

script.onreadystatechange = null;

callback();

}

};

} else { //Others

script.onload = function(){

callback();

};

}

script.src = url;

document.getElementsByTagName_r(“head”)[0].appendChild(script);

}

此函数接收两个参数:JavaScript 文件的URL,和一个当JavaScript 接收完成时触发的回调函数。属性检查用于决定监视哪种事件。最后一步,设置src 属性,并将<script>元素添加至页面。此loadScript()函数

使用方法如下:

loadScript(“file1.js”, function(){

alert(“File is loaded!”);

});

你可以在页面中动态加载很多JavaScript 文件,但要注意,浏览器不保证文件加载的顺序。所有主流浏览器之中,只有Firefox 和Opera 保证脚本按照你指定的顺序执行。其他浏览器将按照服务器返回它们的次序下载并运行不同的代码文件。你可以将下载操作串联在一起以保证他们的次序,如下:

loadScript(“file1.js”, function(){

loadScript(“file2.js”, function(){

loadScript(“file3.js”, function(){

alert(“All files are loaded!”);

});

});

});

此代码等待file1.js 可用之后才开始加载file2.js,等file2.js 可用之后才开始加载file3.js。虽然此方法可行,但如果要下载和执行的文件很多,还是有些麻烦。

如果多个文件的次序十分重要,更好的办法是将这些文件按照正确的次序连接成一个文件。独立文件可以一次性下载所有代码(由于这是异步进行的,使用一个大文件并没有什么损失)。

动态脚本加载是非阻塞JavaScript 下载中最常用的模式,因为它可以跨浏览器,而且简单易用。 本文出自慕课网,转载请注明出处,侵权必究。
4人推荐
随时随地看视频
慕课网APP