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 相关文章推荐
JavaScript Tips 使用DocumentFragment加快DOM渲染速度
Jun 28 Javascript
JS日期和时间选择控件升级版(自写)
Aug 02 Javascript
深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例
Aug 04 Javascript
JS实现倒计时和文字滚动的效果实例
Oct 29 Javascript
javascript创建对象的几种模式介绍
May 06 Javascript
jQuery回到顶部的代码
Jul 09 Javascript
javascript 四十条常用技巧大全
Sep 09 Javascript
工厂模式在JS中的实践
Jan 18 Javascript
JS实现提交表单前的数字及邮箱校检功能
Nov 13 Javascript
Vue.js中对css的操作(修改)具体方式详解
Oct 30 Javascript
微信小程序实现蒙版弹出窗功能
Sep 17 Javascript
jQuery实现简易QQ聊天框
Feb 10 jQuery
在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 daodb插入、更新与删除数据
2009/03/19 PHP
php抓取网站图片并保存的实现方法
2015/10/29 PHP
jQuery向下滚动即时加载内容实现的瀑布流效果
2016/01/07 PHP
完美解决Thinkphp3.2中插入相同数据的问题
2017/08/01 PHP
php apache开启跨域模式过程详解
2019/07/08 PHP
Laravel 5.5 实现禁用用户注册示例
2019/10/24 PHP
IE 条件注释详解总结(附实例代码)
2009/08/29 Javascript
在网页中使用document.write时遭遇的奇怪问题
2010/08/24 Javascript
jquery 跨域访问问题解决方法(笔记)
2011/06/08 Javascript
JS跨域代码片段
2012/08/30 Javascript
jQuery自带的一些常用方法总结
2014/09/03 Javascript
node.js微信公众平台开发教程
2016/03/04 Javascript
nodejs入门教程三:调用内部和外部方法示例
2017/04/24 NodeJs
Angular angular-file-upload文件上传的示例代码
2018/08/23 Javascript
基于JS实现前端压缩上传图片的实例代码
2019/05/14 Javascript
在Vue中使用this.$store或者是$route一直报错的解决
2019/11/08 Javascript
three.js中多线程的使用及性能测试详解
2021/01/07 Javascript
用vite搭建vue3应用的实现方法
2021/02/22 Vue.js
Python中for循环控制语句用法实例
2015/06/02 Python
Python matplotlib画图实例之绘制拥有彩条的图表
2017/12/28 Python
Python中optparser库用法实例详解
2018/01/26 Python
Python实现屏幕截图的两种方式
2018/02/05 Python
Python 爬虫之Beautiful Soup模块使用指南
2018/07/05 Python
python递归实现快速排序
2018/08/18 Python
情人节快乐! python绘制漂亮玫瑰
2020/08/18 Python
浅谈Python爬虫基本套路
2019/03/25 Python
python3实现猜数字游戏
2020/12/07 Python
Python 识别12306图片验证码物品的实现示例
2020/01/20 Python
Windows 平台做 Python 开发的最佳组合(推荐)
2020/07/27 Python
实习护理工作自我评价
2013/09/25 职场文书
中专生自我鉴定范文
2013/12/19 职场文书
法人委托书范本
2014/04/04 职场文书
地球一小时倡议书
2014/04/15 职场文书
股份转让协议书范本
2015/01/27 职场文书
整脏治乱工作简报
2015/07/21 职场文书
Android开发 使用文件储存的方式保存QQ密码
2022/04/24 Java/Android