如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙


Posted in Javascript onMarch 03, 2011

1. 引言
在上一篇文章《如何确保JavaScript的执行顺序 - 之jQuery.html深度分析》中,我们揭示了jQuery.html函数之所以能在各种浏览器下保持动态JS顺序执行,其秘密在于 ? 同步AJAX获取外部JavaScript。
我们先来简单回顾下HTML源代码(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>

顺便一提的是,通过这种方式加载的外部JavaScript不可以在Firebug中调试,因为AJAX结束后外部JavaScript的解析和内联JavaScript的解析是一样的(都是调用jQuery.globalEval):

如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙


下面进入本篇文章的主题:如果加载的JS是在其它域下面的,jQuery.html还能在各个浏览器下都能保证JS的顺序执行么?
2. 建立测试案例
1) 准备两个域名
为了测试,我在个人主页(http://sanshi.me/)下面临时创建了两个子域名,分别是:
http://test.sanshi.me/
http://test1.sanshi.me/
2) 更新Demo页面(test2_1.htm)
我会把test2_1.htm放在第一个子域名下,访问地址为http://test.sanshi.me/jsorder/test2_1.htm,其源代码如下:
<html> 
<head> 
<title></title> 
<script src="js/jquery-1.4.4.js" type="text/javascript"></script> 
<script> 
$(function () { 
$('#container').html('<script src="http://test1.sanshi.me/jsorder/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>

可以看到,其中的jQueryUI脚本指向的是第二个域名下的(test1.sanshi.me)。
3) 在不同浏览器下测试
test2_1.htm 使用jQuery.html函数动态加载其它域下的JavaScript
Firefox 3.6
IE 8
Chrome 10
Safari 4
Opera 11

3. jQuery.html并非万能钥匙,那么
不知道大家是否还记得我们在第一篇文章中提到的test3.htm不,这个结果和那个示例的结果一模一样,jQuery.html也并非万能钥匙。这不禁让我们怀疑这两个示例的内部逻辑是否一样?
但是第二篇文章不是明明白白告诉我们,jQuery.html使用的是同步AJAX的机制来加载外部JS的么?等等。。。。。。
大家有没有从上面的分析中发现问题,AJAX来加载其他域的资源,这不是明摆着违背了大名鼎鼎的同源策略(Same Origin Policy)了么?所以jQuery不可能这么实现,我们来看看jQuery.ajax文档是怎么说的:

如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙

看来我们在第二篇文章中看到的这个函数(evalScript)内部并非真的通过同步AJAX来获取数据:

如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙


4. 深入jQuery.ajax函数,看看怎么加载不同域下的JS文件

如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙

注释已经写的很清楚了,如果是通过GET方式请求JavaScript文件,并且这个文件是在其他域下面的(remote),那么就通过在head中添加script标签来处理,而不是走AJAX的流程。所以在这个条件分支结束的时候,直接从函数体返回:

如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙

经过分析,我们发现在动态加载不同域的JavaScript时,jQuery.html其实采用了在head中添加script标签的做法(不管是外部JS或者内联JS),这和我们在第一篇文章中提到的test3.htm是一模一样的逻辑,这也验证了我们的想法:

如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙

 

由此可见,如果想兼容CDN加速静态资源的情况,还必须使用第一篇文章中提到的“方案一,如何在动态添加script标签时确保执行顺序”。

5.     后记

本来这个系列的文章到这就应该结束了。不过在我测试jQuery1.5.1后,居然发现和我用的jQuery1.4.4是有差异的,早就听说jQuery1.5.1AJAX部分进行了重构,没想到还真的对我们的代码有点影响。

 

具体是哪方面的影响,请看下一篇文章:如何确保JavaScript的执行顺序 - jQuery1.5.1jQuery1.4.4的细微差异。待续。。。

Javascript 相关文章推荐
javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号
Jul 21 Javascript
js 调用本地exe的例子(支持IE内核的浏览器)
Dec 26 Javascript
JavaScript基础教程之alert弹出提示框实例
Oct 16 Javascript
javascript面向对象之定义成员方法实例分析
Jan 13 Javascript
举例讲解JavaScript substring()的使用方法
Nov 09 Javascript
JavaScript和jQuery制作光棒效果
Feb 24 Javascript
layui select获取自定义属性方法
Aug 15 Javascript
从vue源码解析Vue.set()和this.$set()
Aug 30 Javascript
解决vue单页路由跳转后scrollTop的问题
Sep 03 Javascript
对vue下点击事件传参和不传参的区别详解
Sep 15 Javascript
如何使用50行javaScript代码实现简单版的call,apply,bind
Aug 14 Javascript
JavaScript十大取整方法实例教程
Dec 03 Javascript
如何确保JavaScript的执行顺序 之jQuery.html深度分析
Mar 03 #Javascript
jQuery 操作option的实现代码
Mar 03 #Javascript
基于Jquery的$.cookie()实现跨越页面tabs导航实现代码
Mar 03 #Javascript
jquery中实现简单的tabs插件功能的代码
Mar 02 #Javascript
基于jQuery的简单的列表导航菜单
Mar 02 #Javascript
jquery异步调用页面后台方法&amp;#8207;(asp.net)
Mar 01 #Javascript
jQuery获取文本节点之 text()/val()/html() 方法区别
Mar 01 #Javascript
You might like
php提示Failed to write session data错误的解决方法
2014/12/17 PHP
深入浅析Yii admin的权限控制
2016/08/31 PHP
不常用但很实用的PHP预定义变量分析
2019/06/25 PHP
javascrip客户端验证文件大小及文件类型并重置上传
2011/01/12 Javascript
js实现键盘上下左右键选择文字并显示在文本框的方法
2015/05/07 Javascript
JQueryEasyUI框架下的combobox的取值和绑定的方法
2017/01/22 Javascript
使用 NodeJS+Express 开发服务端的简单介绍
2017/04/07 NodeJs
bootstrap multiselect 多选功能实现方法
2017/06/05 Javascript
angularjs2中父子组件的数据传递的实例代码
2017/07/05 Javascript
Vue中使用 setTimeout() setInterval()函数的问题
2018/09/13 Javascript
Vue 幸运大转盘实现思路详解
2019/05/06 Javascript
简单学习5种处理Vue.js异常的方法
2019/06/17 Javascript
layui 富文本图片上传接口与普通按钮 文件上传接口的例子
2019/09/23 Javascript
JS+CSS实现随机点名(实例代码)
2019/11/04 Javascript
vue实现简单跑马灯效果
2020/05/25 Javascript
详解vue之自行实现派发与广播(dispatch与broadcast)
2021/01/19 Vue.js
[02:18]DOTA2英雄基础教程 育母蜘蛛
2014/01/20 DOTA
[01:07]DOTA2次级职业联赛 - Fpb战队宣传片
2014/12/01 DOTA
python基于windows平台锁定键盘输入的方法
2015/03/05 Python
python识别图像并提取文字的实现方法
2019/06/28 Python
Django 简单实现分页与搜索功能的示例代码
2019/11/07 Python
python中matplotlib实现随鼠标滑动自动标注代码
2020/04/23 Python
Python 爬虫性能相关总结
2020/08/03 Python
matplotlib事件处理基础(事件绑定、事件属性)
2021/02/03 Python
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
美国领先的医疗警报服务:Philips Lifeline
2018/03/12 全球购物
Rentalcars.com中国:世界上最大的在线汽车租赁服务
2019/08/22 全球购物
机械专业应届毕业生自荐书
2014/06/12 职场文书
教师节感恩老师演讲稿
2014/08/28 职场文书
领导班子在批评与自我批评座谈会上的发言
2014/09/28 职场文书
2015年社区矫正工作总结
2015/04/21 职场文书
《一面五星红旗》教学反思
2016/02/23 职场文书
小学生作文写作技巧100例,非常实用!
2019/07/08 职场文书
五年级作文之成长
2019/09/16 职场文书
导游词之贵州百里杜鹃
2019/10/29 职场文书
python的变量和简单数字类型详解
2021/09/15 Python