如何确保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 相关文章推荐
初学js插入节点appendChild insertBefore使用方法
Jul 04 Javascript
js 为label标签和div标签赋值的方法
Aug 08 Javascript
javascript实现禁止右键和F12查看源代码
Dec 26 Javascript
JavaScript基本数据类型及值类型和引用类型
Aug 25 Javascript
基于JavaScript实现生成名片、链接等二维码
Sep 20 Javascript
轻松使用jQuery双向select控件Bootstrap Dual Listbox
Dec 13 Javascript
浅谈Sticky组件的改进实现
Mar 22 Javascript
微信小程序多张图片上传功能
Jun 07 Javascript
Js自定义多选框效果的实例代码
Jul 05 Javascript
vue中typescript装饰器的使用方法超实用教程
Jun 17 Javascript
Node登录权限验证token验证实现的方法示例
May 25 Javascript
vue监听滚动事件的方法
Dec 21 Vue.js
如何确保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作的文本留言本的例子(六)
2006/10/09 PHP
MySQL数据库转移,access,sql server 转 MySQL 的图文教程
2007/09/02 PHP
网友原创的PHP模板类代码
2008/09/07 PHP
PHP获取本周第一天和最后一天示例代码
2014/02/24 PHP
PHP实现对文本数据库的常用操作方法实例演示
2014/07/04 PHP
PHP实现HTTP断点续传的方法
2015/06/17 PHP
教你在PHPStorm中配置Xdebug
2015/07/27 PHP
jquery将一个表单序列化为一个对象的方法
2014/01/03 Javascript
jQueryMobile之Helloworld与页面切换的方法
2015/02/04 Javascript
Jquery uploadify上传插件使用详解
2016/01/13 Javascript
Atitit.js的键盘按键事件捆绑and事件调度
2016/04/01 Javascript
微信小程序使用canvas自适应屏幕画海报并保存图片功能
2019/07/25 Javascript
小程序开发之模态框组件封装
2020/04/23 Javascript
vue3+typeScript穿梭框的实现示例
2020/12/29 Vue.js
Tensorflow卷积神经网络实例
2018/05/24 Python
解决Python一行输出不显示的问题
2018/12/03 Python
学习python可以干什么
2019/02/26 Python
Python为何不能用可变对象作为默认参数的值
2019/07/01 Python
详解Python Qt的窗体开发的基本操作
2019/07/14 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
python PIL/cv2/base64相互转换实例
2020/01/09 Python
python进行参数传递的方法
2020/05/12 Python
python中re模块知识点总结
2021/01/17 Python
澳大利亚在线家具店:Luxo Living
2019/03/24 全球购物
洛佩桑酒店官方网站:Lopesan Hotels
2019/04/15 全球购物
荣耀俄罗斯官网:HONOR俄罗斯
2020/10/31 全球购物
对于没有初始化的变量的初始值可以作怎样的假定
2014/10/12 面试题
如何整合JQuery和Prototype
2014/01/31 面试题
业务经理的岗位职责
2013/11/16 职场文书
社团招新策划书
2014/02/04 职场文书
五一活动标语
2014/06/30 职场文书
垃圾分类的活动方案
2014/08/15 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
三八节活动主持词
2015/07/04 职场文书
升学宴家长致辞
2015/07/27 职场文书
详解python网络进程
2021/06/15 Python