如何确保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实现Sleep函数的代码
Mar 04 Javascript
js 弹出框 替代浏览器的弹出框
Oct 29 Javascript
jQuery操作Select的Option上下移动及移除添加等等
Nov 18 Javascript
探讨javascript是不是面向对象的语言
Nov 21 Javascript
angularJS提交表单(form)
Feb 09 Javascript
ionic实现底部分享功能
May 11 Javascript
layui分页效果实现代码
May 19 Javascript
JavaScript之map reduce_动力节点Java学院整理
Jun 29 Javascript
vue通过v-html指令渲染的富文本无法修改样式的解决方案
May 20 Javascript
javascript实现移动端上传图片功能
Aug 18 Javascript
js+h5 canvas实现图片验证码
Oct 11 Javascript
vue 全局封装loading加载教程(全局监听)
Nov 05 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约瑟夫问题解决关于处死犯人的算法
2015/03/23 PHP
php中判断数组相等的方法以及数组运算符介绍
2015/03/30 PHP
PHP去除字符串最后一个字符的三种方法实例
2017/03/01 PHP
解析jquery获取父窗口的元素
2013/06/26 Javascript
原生JS实现加入收藏夹的代码
2013/10/24 Javascript
jQuery操作cookie方法实例教程
2014/11/25 Javascript
对JavaScript中this指针的新理解分享
2015/01/31 Javascript
Bootstrap面板使用方法
2017/01/16 Javascript
vue中v-model动态生成的实例详解
2017/10/27 Javascript
Vue2.0用户权限控制解决方案的示例
2018/02/10 Javascript
vue路由拦截及页面跳转的设置方法
2018/05/24 Javascript
vuejs选中当前样式active的实例
2018/08/22 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
2018/09/07 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
three.js如何实现3D动态文字效果
2021/03/03 Javascript
Python 列表list使用介绍
2014/11/30 Python
利用Python开发微信支付的注意事项
2016/08/19 Python
Python对List中的元素排序的方法
2018/04/01 Python
树莓派用python中的OpenCV输出USB摄像头画面
2019/06/22 Python
python防止随意修改类属性的实现方法
2019/08/21 Python
python实现单链表的方法示例
2019/09/03 Python
通过实例了解Python str()和repr()的区别
2020/01/17 Python
python进度条显示-tqmd模块的实现示例
2020/08/23 Python
Lookfantastic阿联酋官网:英国知名美妆护肤购物网站
2020/05/26 全球购物
《三峡》教学反思
2014/03/01 职场文书
《水上飞机》教学反思
2014/04/10 职场文书
省级青年文明号申报材料
2014/05/23 职场文书
学校三八妇女节活动总结
2015/02/06 职场文书
大客户经理岗位职责
2015/04/09 职场文书
停电放假通知
2015/04/14 职场文书
行政答辩状范文
2015/05/21 职场文书
实施意见格式范本
2015/06/05 职场文书
初中生物教学反思
2016/02/20 职场文书
2019垃圾分类宣传口号汇总
2019/08/16 职场文书
Vue elementUI表单嵌套表格并对每行进行校验详解
2022/02/18 Vue.js
Java 超详细讲解IO操作字节流与字符流
2022/03/25 Java/Android