jQuery 源码分析笔记(4) Ready函数


Posted in Javascript onJune 02, 2011

这个功能在 jQuery的文档中提到了三种等价的形式:

// 定义在jQuery.fn.ready 
$(document).ready(handler); 
// 和上一个是同一个,不推荐 
$().ready(handler); 
// 单独在jQuery对象中处理 
$(handler); 
// 以上这个形式的定义: 
if(jQuery.isFunction(selector) { 
return rootjQuery.ready(selector); 
}

因此实际上都归结与一个形式:jQuery.fn.ready(fn)。定义如下:
ready: function(fn) { 
// 绑定事件到DOM上 
jQuery.bindReady(); 
// 触发回调函数 
readyList.done(fn); 
// 返回jQuery对象 
return this; 
}

实际上jQuery内部并不仅仅只有一个对fn的引用。这里用到了 Deferred功能。在75行,为jQuery对象定义了readyList成员。而在442行在bindReady函数中初始化了这个变量:
if(readyList) { 
return; 
} 
readyList = jQuery._Deferred();

bindReady函数除了初始化readyList之外,主要处理了浏览器对于绑定事件的区别。IE使用attachEvent而其他浏览器使用addEventHandler。这两个步骤完成后,ready函数使用readyList.resolveWith 触发回调函数。除了这个工作外,ready还处理了holdReady。这个API 的作用是延迟ready事件的回调,主要目的是在ready事件前做点事情。holdReady设置了一个标志位readyWait。当这个标志位被设置之后,ready在调用readyList.resolveWith之前不停地调用setTimeout(jQuery.ready, 1)。即每隔固定时间就递归调用自己(不知道hold时间久了,js引擎会不会栈溢出),这样最后被holdReady释放的时候, setTimeout会沿着调用栈回来的。为了在这个栈完成之前不触发ready回调函数。在每次调用setTimeout的时候,会递增readyWait变量。用来指示被holdReady函数延误了几次调用。

###几个基础辅助函数
在543行开始,定义了几个值得注意的辅助函数:parseJSON,parseXML和globalEval。parseJSON把一个字符串变成JSON对象。我们一般使用的是eval。parseJSON封装了这个操作,但是eval被当作了最后手段。因为最新JavaScript标准中加入了JSON序列化和反序列化的API。如果浏览器支持这个标准,则这两个API是在JS引擎中用Native Code实现的,效率肯定比eval高很多。目前来看,Chrome和Firefox4都支持这个API。parseJSON使用如下:

// 原生JSON API。反序列化是JSON.stringify(object) 
if(window.JSON && window.JSON.parse) { 
return window.JSON.parse(data); 
} 
// ... 大致地检查一下字符串合法性 
return (new Function("return " + data))();

parseXML函数也主要是标准API和IE的封装。标准API是DOMParser对象。而IE使用的是Microsoft.XMLDOM的 ActiveXObject对象。定义:
if(window.DOMParser) { 
tmp = new DOMParser(); 
xml = tmp.parseFromString(data, "text/xml"); 
} else { 
xml = new ActiveXObject("Microsoft.XMLDOM"); 
xml.async = "false"; 
xml.loadXML(data); 
}

globalEval函数把一段脚本加载到全局context中。IE中可以使用window.execScript。其他浏览器需要使用eval。因为整个jQuery代码都是一整个匿名函数,所以当前context是jQuery。主要代码:
(window.execScript || function(data) { 
window["eval"].call(window, data); // 在window context下运行 
})(data);
Javascript 相关文章推荐
js实现一个省市区三级联动选择框代码分享
Mar 06 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
Oct 23 Javascript
js实现获取焦点后光标在字符串后
Sep 17 Javascript
angularjs中的单元测试实例
Dec 06 Javascript
JavaScript控制两个列表框listbox左右交换数据的方法
Mar 18 Javascript
全面解析Bootstrap布局组件应用
Feb 22 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
Feb 09 Javascript
Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信
Feb 23 Javascript
基于javascript 显式转换与隐式转换(详解)
Dec 15 Javascript
vue项目实战总结篇
Feb 11 Javascript
[原创]jquery判断元素内容是否为空的方法
May 04 jQuery
JavaScript中常用的3种弹出提示框(alert、confirm、prompt)
Nov 10 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
Jun 02 #Javascript
JqGrid web打印实现代码
May 31 #Javascript
16个最流行的JavaScript框架[推荐]
May 29 #Javascript
js 静态动态成员 and 信息的封装和隐藏
May 29 #Javascript
在JavaScript中监听IME键盘输入事件
May 29 #Javascript
解读JavaScript代码 var ie = !-[1,] 最短的IE判定代码
May 28 #Javascript
Jquery css函数用法(判断标签是否拥有某属性)
May 28 #Javascript
You might like
PHP 冒泡排序算法的实现代码
2010/08/08 PHP
javascript 异常处理使用总结
2009/06/21 Javascript
jQuery Ajax之$.get()方法和$.post()方法
2009/10/12 Javascript
js借助ActiveXObject实现创建文件
2013/09/29 Javascript
javascript实现动态改变层大小的方法
2015/05/14 Javascript
jQuery简单获取键盘事件的方法
2016/01/22 Javascript
懒加载实现的分页&&网站footer自适应
2016/12/21 Javascript
javascript操作cookie
2017/01/17 Javascript
JS数组去重(4种方法)
2017/03/27 Javascript
nodejs mysql 实现分页的方法
2017/06/06 NodeJs
jquery实现限制textarea输入字数的方法
2017/09/06 jQuery
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
2017/10/24 Javascript
详解weex默认webpack.config.js改造
2018/01/08 Javascript
JavaScript中变量提升和函数提升的详解
2020/08/07 Javascript
js+cavans实现图片滑块验证
2020/09/29 Javascript
JavaScript实现五子棋小游戏
2020/10/26 Javascript
Python基于twisted实现简单的web服务器
2014/09/29 Python
python修改注册表终止360进程实例
2014/10/13 Python
tensorflow学习笔记之mnist的卷积神经网络实例
2018/04/15 Python
Python实现随机生成手机号及正则验证手机号的方法
2018/04/25 Python
python MNIST手写识别数据调用API的方法
2018/08/08 Python
Python爬取数据保存为Json格式的代码示例
2019/04/09 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
python基于opencv检测程序运行效率
2019/12/28 Python
Python 中@property的用法详解
2020/01/15 Python
文件上传服务器-jupyter 中python解压及压缩方式
2020/04/22 Python
20行代码教你用python给证件照换底色的方法示例
2021/02/05 Python
纪伊国屋泰国网上书店:Kinokuniya泰国
2017/12/24 全球购物
Windows和Linux动态库应用异同
2016/04/17 面试题
职位说明书范文
2014/05/07 职场文书
2015年卫生监督工作总结
2015/05/21 职场文书
2016年五一促销广告语
2016/01/28 职场文书
MyBatis自定义SQL拦截器示例详解
2021/10/24 Java/Android
springmvc直接不经过controller访问WEB-INF中的页面问题
2022/02/24 Java/Android
Win10 heic文件怎么打开 ? Win10 heic文件打开教程
2022/04/06 数码科技
Win11查看设备管理器
2022/04/19 数码科技