如何确保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中的onerror事件概述及使用
Apr 01 Javascript
Jquery中children与find之间的区别详细解析
Nov 29 Javascript
jQuery判断数组是否包含了指定的元素
Mar 10 Javascript
基于jQuery实现歌词滚动版音乐播放器的代码
Sep 17 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
Apr 10 Javascript
JS按条件 serialize() 对应标签的使用方法
Jul 24 Javascript
解决layui 复选框等内置控件不显示的问题
Aug 14 Javascript
JavaScript格式化json和xml的方法示例
Jan 22 Javascript
vue-cli构建vue项目的步骤详解
Jan 27 Javascript
微信小程序 腾讯地图显示偏差问题解决
Jul 27 Javascript
浅谈TypeScript的类型保护机制
Feb 23 Javascript
vscode调试node.js的实现方法
Mar 22 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笔记之:文章中图片处理的使用
2013/04/26 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
PHP实现的数独求解问题示例
2017/04/18 PHP
PHP预定义超全局数组变量小结
2018/08/20 PHP
js multiple全选与取消全选实现代码
2012/12/04 Javascript
jquery购物车实时结算特效实现思路
2013/09/23 Javascript
Jquery 动态循环输出表格具体方法
2013/11/23 Javascript
js数组方法扩展实现数组统计函数
2014/04/09 Javascript
javascript 中__proto__和prototype详解
2014/11/25 Javascript
DOM节点的替换或修改函数replaceChild()用法实例
2015/01/12 Javascript
js淡入淡出的图片轮播效果代码分享
2015/08/24 Javascript
javascript中递归的两种写法
2017/01/17 Javascript
NodeJs测试框架Mocha的安装与使用
2017/03/28 NodeJs
JS闭包的几种常见形式实例详解
2017/09/16 Javascript
在AngularJs中设置请求头信息(headers)的方法及不同方法的比较
2018/09/04 Javascript
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
详解wepy开发小程序踩过的坑(小结)
2019/05/22 Javascript
在layui tab控件中载入外部html页面的方法
2019/09/04 Javascript
JavaScript 作用域scope简单汇总
2019/10/23 Javascript
vue中beforeRouteLeave实现页面回退不刷新的示例代码
2019/11/01 Javascript
Vue快速实现通用表单验证的示例代码
2020/01/09 Javascript
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
关于Python元祖,列表,字典,集合的比较
2017/01/06 Python
python中类和实例如何绑定属性与方法示例详解
2017/08/18 Python
python中利用await关键字如何等待Future对象完成详解
2017/09/07 Python
Python探索之Metaclass初步了解
2017/10/28 Python
python实现屏保计时器的示例代码
2018/08/08 Python
通用的Django注册功能模块实现方法
2021/02/05 Python
详解CSS3媒体查询响应式布局bootstrap 框架原理实战(推荐)
2020/11/16 HTML / CSS
英国123鲜花网站:123 Flowers
2019/07/07 全球购物
入党自我评价优缺点
2014/01/25 职场文书
市场专员岗位职责
2014/02/14 职场文书
2014年反腐倡廉工作总结
2014/12/05 职场文书
工程部岗位职责范本
2015/04/11 职场文书
HTML+css盒子模型案例(圆,半圆等)“border-radius” 简单易上手
2021/05/10 HTML / CSS
Python OpenCV形态学运算示例详解
2022/04/07 Python