手机
当前位置:查字典教程网 >编程开发 >Javascript教程 >如何确保JavaScript的执行顺序 之实战篇
如何确保JavaScript的执行顺序 之实战篇
摘要:1.引言我曾在文章《如何在多个页面使用同一个HTML片段-续》的最后提到JavaScript顺序执行的特性。虽然现代浏览器可以并行的下载Ja...

1. 引言

我曾在文章《如何在多个页面使用同一个HTML片段 - 续》的最后提到JavaScript顺序执行的特性。虽然现代浏览器可以并行的下载JavaScript(部分浏览器),但考虑到JavaScript的依赖关系,他们的执行依然是按照引入顺序进行的。

为了更好的测试这个过程,我写了一个简单的HTTP处理程序页面 service.ashx,它可以接受两个参数:

1. file,需要返回文件的服务器端路径。

2. delay,延迟一定时间后再返回本次HTTP请求(毫秒)。

一个典型的页面比如:./service.ashx?file=js/jquery-ui.js&delay=2000,表示延迟2秒钟后再返回服务器端的js/jquery-ui.js文件。

service.ashx 的关键代码如下:

复制代码 代码如下:

public void ProcessRequest(HttpContext context)

{

int delay = 0;

if (!String.IsNullOrEmpty(context.Request["delay"]))

{

delay = Convert.ToInt32(context.Request["delay"]);

}

if (delay > 0)

{

System.Threading.Thread.Sleep(1000);

}

string filePath = context.Request["file"].ToString();

string fileContent = String.Empty;

using (StreamReader sr = new StreamReader(context.Server.MapPath(filePath)))

{

fileContent = sr.ReadToEnd();

}

if (filePath.EndsWith(".js"))

{

context.Response.ContentType = "application/x-javascript";

}

else

{

context.Response.ContentType = "text/plain";

}

context.Response.Write(fileContent);

}

2. 通过script标签直接引入JavaScript(test1.htm)

首先我们分析下在<head>标签中顺序引入JavaScript的情况。test1.htm的页面源代码如下:

复制代码 代码如下:

<html>

<head>

<title></title>

<script src="./js/jquery-1.4.4.js"

type="text/javascript"></script>

<script src="./service.ashx?file=js/jquery-ui.js&delay=2000"

type="text/javascript"></script>

<script>

alert(typeof (jQuery.ui));

</script>

</head>

<body>

</body>

</html>

我们分别在各种浏览器中测试这个例子:

test1.htm

通过script标签直接引入JavaScript

Firefox 3.6

如何确保JavaScript的执行顺序 之实战篇1

IE 8

如何确保JavaScript的执行顺序 之实战篇2

Chrome 10

如何确保JavaScript的执行顺序 之实战篇3

Safari 4

如何确保JavaScript的执行顺序 之实战篇4

Opera 11

如何确保JavaScript的执行顺序 之实战篇5

可以看出各个主流浏览器的行为一致。虽然jQueryUI在服务器延迟了2秒钟再返回,但是后引入的内联JavaScript还是等待了2秒,等前面引入的JavaScript执行完毕才执行。这也是著名的JavaScript顺序执行的特性。

3. 通过JavaScript添加script标签(test3.htm)

我们首先定义一个addScript函数,用来引入外部或者内联JavaScript。test3.htm的页面源代码如下:

复制代码 代码如下:

<html>

<head>

<title></title>

<script src="./js/jquery-1.4.4.js" type="text/javascript"></script>

<script>

function addScript(url, inline) {

var head = document.getElementsByTagName("head")[0];

var script = document.createElement('script');

script.type = 'text/javascript';

if (inline) {

script.text = url;

} else {

script.src = url;

}

head.appendChild(script);

}

$(function () {

addScript('./service.ashx?file=js/jquery-ui.js&delay=2000');

addScript('alert(typeof(jQuery.ui));', true);

});

</script>

</head>

<body>

<div id="container">

</div>

</body>

</html>

我们分别在各种浏览器中测试这个例子:

test3.htm

通过JavaScript添加<script>标签

Firefox 3.6

如何确保JavaScript的执行顺序 之实战篇1

IE 8

如何确保JavaScript的执行顺序 之实战篇6

Chrome 10

如何确保JavaScript的执行顺序 之实战篇7

Safari 4

如何确保JavaScript的执行顺序 之实战篇8

Opera 11

如何确保JavaScript的执行顺序 之实战篇5

可见,通过JavaScript在DOM加载完毕后再引入外部或者内联JavaScript时,Firefox和Opera的行为一致,能够确保JavaScript的执行顺序和引入顺序一致。但是IE8, Chrome, Safari 却不能保证这个执行顺序。

虽然各种浏览器在确保执行顺序方面不尽相同,不过这时的最大好处是多个JavaScript文件能够并行下载,这在所有浏览器中行为一致。当然这不是这篇文章的主题,可以Google更多细节。

如何解决各个浏览器的不一致性,下面提供了两个解决方案:

4. 方案一,如何在动态添加script标签时确保执行顺序

有时页面逻辑要求我们必须通过上面的方式动态执行JavaScript,那么如何确保所有浏览器下的执行顺序(目前只有Firefox和Opera确保执行顺序)。

其实解决方案很简单,我们为函数执行添加一个complete的回调函数就行了。下面的test4.htm给出了具体的解决方案:

复制代码 代码如下:

<html>

<head>

<title></title>

<script src="./js/jquery-1.4.4.js" type="text/javascript"></script>

<script>

function addScript(url, inline, callback) {

var head = document.getElementsByTagName("head")[0];

var script = document.createElement('script');

script.type = 'text/javascript';

if (inline) {

script.text = url;

} else {

script.src = url;

script.onload = script.onreadystatechange = function () {

if (!script.readyState || script.readyState === 'loaded' || script.readyState === 'complete') {

if (callback) {

callback();

}

script.onload = script.onreadystatechange = null;

};

};

}

head.appendChild(script);

if (inline && callback) {

callback();

}

}

$(function () {

addScript('./service.ashx?file=js/jquery-ui.js&delay=2000', false, function () {

addScript('alert(typeof(jQuery.ui));', true);

});

});

</script>

</head>

<body>

<div id="container">

</div>

</body>

</html>

此时所有浏览器中的行为一致:

test4.htm

通过回调函数解决动态添加JavaScript的顺序问题

Firefox 3.6

如何确保JavaScript的执行顺序 之实战篇1

IE 8

如何确保JavaScript的执行顺序 之实战篇2

Chrome 10

如何确保JavaScript的执行顺序 之实战篇3

Safari 4

如何确保JavaScript的执行顺序 之实战篇4

Opera 11

如何确保JavaScript的执行顺序 之实战篇5

5. 方案二,使用jQuery的html函数动态添加JavaScript

jQuery的html函数用来更新一个DOM片段,我们可以很方便的通过这个函数来动态加载JavaScript,请看示例test2.htm:

复制代码 代码如下:

<html>

<head>

<title></title>

<script src="js/jquery-1.4.4.js" type="text/javascript"></script>

<script>

$(function(){

$('#container').html('<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text/javascript"></script>' + '<script>alert(typeof(jQuery.ui));</script>');

});

</script>

</head>

<body>

<div id="container">

</div>

</body>

</html>

此时,各个浏览器中的行为一致:

test2.htm

通过jQuery的html函数解决动态添加JavaScript的顺序问题

Firefox 3.6

如何确保JavaScript的执行顺序 之实战篇1

IE 8

如何确保JavaScript的执行顺序 之实战篇2

Chrome 10

如何确保JavaScript的执行顺序 之实战篇3

Safari 4

如何确保JavaScript的执行顺序 之实战篇4

Opera 11

如何确保JavaScript的执行顺序 之实战篇5

6. 后记

为什么jQuery的html函数能够确保动态加载JavaScript的执行顺序呢?

我们知道通过简单的 .innerHTML 更新DOM节点,是不会让其中的JavaScript的执行,我们可以简单的把这个例子的源代码改成:

$('#container')[0].innerHTML = '<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text/javascript"></script>' + '<script>alert(typeof(jQuery.ui));</script>';

这种情况下jQueryUI根本不会加载。

那么jQuery是如果做到的呢?下篇文章我们会追根溯源,详细分析jQuery源代码,请继续浏览: 如何确保JavaScript的执行顺序 – 之jQuery.html深度分析

【如何确保JavaScript的执行顺序 之实战篇】相关文章:

javascript瀑布流式图片懒加载实例

浅析JavaScript中的事件机制

原生javascript实现解析XML文档与字符串

使用JavaScript刷新网页的方法

JavaScript版代码高亮

JavaScript的正则表达式中test()方法的使用

JavaScript中的Math.SQRT1_2属性使用简介

JavaScript对传统文档对象模型的支持

实现高性能JavaScript之执行与加载

JavaScript中用toString()方法返回时间为字符串

精品推荐
分类导航