jQuery-1.9.1源码分析系列(六) 延时对象应用——jQuery.ready
还记不记得jQuery初始化函数jQuery.fn.init中有这样是一个分支
//document ready简便写法$(function(){…})
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
所以$(fn)===$(document).ready(fn)。
来看一下jQuery.fn.ready的源码
ready: function( fn ) {
// Add the callback
jQuery.ready.promise().done( fn ); return this;
}
很明显在jQuery.ready.promise函数中设置了延时,当延时对象解决的时候执行fn函数。
主要的处理流程:
创建一个延时对象,并将文档准备好后的处理事件添加到该延时对象成功事件列表上。
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
readyList = jQuery.Deferred(); ... }
return readyList.promise( obj );
}
添加文档准备状态的监听函数(jQuery.ready.promise函数片段)
//标准浏览器支持DOMContentLoaded事件
} else if ( document.addEventListener ) {
//绑定DOMContentLoaded事件和响应函数,响应函数会解决延时
document.addEventListener( "DOMContentLoaded", completed, false ); //回退到window.onload事件绑定,所有的浏览器都支持
window.addEventListener( "load", completed, false ); //如果是IE事件模型
} else {
//确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全
document.attachEvent( "onreadystatechange", completed ); //回退到window.onload事件绑定,所有的浏览器都支持
window.attachEvent( "onload", completed ); //如果IE并且不是一个frame
//不断地检查,看是否该文件已准备就绪
var top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
if ( top && top.doScroll ) {
(function doScrollCheck() {
if ( !jQuery.isReady ) {
try {
// Use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
} //移除之前绑定的事件
detach(); //执行延迟
jQuery.ready();
}
})();
}
}
一旦监听到文档准备完成,则调用jQuery.ready执行延时对象的成功回调列表:即所有通过jQuery.ready(fn)【或jQuery(fn)】方式添加的函数fn。
//ready事件处理函数
completed = function( event ) {
// readyState === "complete"在老版本IE上适用
if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
detach();
jQuery.ready();
}
},
//清除ready事件绑定
detach = function() {
if ( document.addEventListener ) {
document.removeEventListener( "DOMContentLoaded", completed, false );
window.removeEventListener( "load", completed, false ); } else {
document.detachEvent( "onreadystatechange", completed );
window.detachEvent( "onload", completed );
}
};
//处理当DOM准备完成
jQuery.ready: function( wait ) {
...
//设置DOM已经准备好的标志
jQuery.isReady = true;
...
//执行绑定的延时事件
readyList.resolveWith( document, [ jQuery ] );
//触发任何绑定的就绪事件
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
}
}
整个过程就是如此。其中有一些小的知识点整理一下。
a. 文档加载状态document.readyState
document.readyState用来判断文档加载状态,是一个只读属性,可能的值有:
0-uninitialized:XML 对象被产生,但没有任何文件被加载。
1-loading:加载程序进行中,但文件尚未开始解析。
2-loaded:部分的文件已经加载且进行解析,但对象模型尚未生效。
3-interactive:仅对已加载的部分文件有效,在此情况下,对象模型是有效但只读的。
4-complete:文件已完全加载,代表加载成功。
实例:
document.onreadystatechange = stateChange;//当页面加载状态改变的时候执行这个方法.
function stateChange() {
if(document.readyState == "complete"){ //当页面加载状态为完全结束时进入
alert("文档加载成功")
}
}
但是,老版本的Firefox并不支持document.readyState【最新的Firefox已经支持了】。所以想要兼容所有浏览器监听文档准备完成分两种情况来处理:
- 标准浏览器使用addEventListener添加DOMContentLoaded和load监听,任何一个事件被触发即可
- 老版本IE浏览器使用attachEvent添加onreadystatechange和onload来监听,任何一个被触发,并且onreadystatechange时document.readyState === "complete"即可。
jQuery的处理也就是如此了
jQuery.ready.promise = function(){
...
//标准浏览器支持DOMContentLoaded事件
else if ( document.addEventListener ) {
//绑定DOMContentLoaded事件和响应函数,响应函数会解决延时
document.addEventListener( "DOMContentLoaded", completed, false ); //回退到window.onload事件绑定,所有的浏览器都支持
window.addEventListener( "load", completed, false ); //如果是IE事件模型
} else {
//确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全
document.attachEvent( "onreadystatechange", completed ); //回退到window.onload事件绑定,所有的浏览器都支持
window.attachEvent( "onload", completed );
...
}
}
//ready事件处理函数
completed = function( event ) {
// readyState === "complete"在老版本IE上适用
if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
detach();
jQuery.ready();
}
}
b.doScroll检测文档加载完成
这是Diego Perini 发现的一种检测IE是否加载完成的方式。详细链接
原理是当页面 DOM 未加载完成时调用 doScroll 方法时会产生异常。那么不断的取检测异常是否发生就可以知道文档有没有加载完成。当没有发生异常,表明文档加载完成了。
(function doScrollCheck() {
if ( !jQuery.isReady ) {
try {
// Use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
} //移除之前绑定的事件
detach(); //执行延迟
jQuery.ready();
}
})();
如果觉得本文不错,请点击右下方【推荐】!
jQuery-1.9.1源码分析系列(六) 延时对象应用——jQuery.ready的更多相关文章
- jQuery源码分析系列(一)初识jQuery
一个工厂 (function(global, factory){ "use strict" // operation_1 })(typedef window !== "u ...
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- [转]jQuery源码分析系列
文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...
- jQuery源码分析系列(转载来源Aaron.)
声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...
- jQuery源码分析系列——来自Aaron
jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...
- jquery2源码分析系列
学习jquery的源码对于提高前端的能力很有帮助,下面的系列是我在网上看到的对jquery2的源码的分析.等有时间了好好研究下.我们知道jquery2开始就不支持IE6-8了,从jquery2的源码中 ...
- jQuery-1.9.1源码分析系列完毕目录整理
jQuery 1.9.1源码分析已经完毕.目录如下 jQuery-1.9.1源码分析系列(一)整体架构 jQuery-1.9.1源码分析系列(一)整体架构续 jQuery-1.9.1源码分析系列(二) ...
- MyCat源码分析系列之——结果合并
更多MyCat源码分析,请戳MyCat源码分析系列 结果合并 在SQL下发流程和前后端验证流程中介绍过,通过用户验证的后端连接绑定的NIOHandler是MySQLConnectionHandler实 ...
- MyCat源码分析系列之——SQL下发
更多MyCat源码分析,请戳MyCat源码分析系列 SQL下发 SQL下发指的是MyCat将解析并改造完成的SQL语句依次发送至相应的MySQL节点(datanode)的过程,该执行过程由NonBlo ...
- MyCat源码分析系列之——BufferPool与缓存机制
更多MyCat源码分析,请戳MyCat源码分析系列 BufferPool MyCat的缓冲区采用的是java.nio.ByteBuffer,由BufferPool类统一管理,相关的设置在SystemC ...
随机推荐
- Awstats显示国家地区插件GeoIP安装
Awstats默认安装之后是不具有识别访问者的国家和地区信息的,所以需要安装插件支持Awstats列出访问者的国家和地区,便于分析GeoIP免费的是国家/IP的数据表,GeoIPCityLite是地区 ...
- Hadoop学习笔记—6.Hadoop Eclipse插件的使用
开篇:Hadoop是一个强大的并行软件开发框架,它可以让任务在分布式集群上并行处理,从而提高执行效率.但是,它也有一些缺点,如编码.调试Hadoop程序的难度较大,这样的缺点直接导致开发人员入门门槛高 ...
- nodejs事件轮询详述
目录 概述 nodejs特点 事件轮询 关于异步方法 概述 关于nodejs的介绍网上资料非常多,最近由于在整理一些函数式编程的资料时,多次遇到nodejs有关的内容.所以就打算专门写一篇文章总结一下 ...
- 迷你MVVM框架avalon在兼容旧式IE做的努力
很多时候,写代码就像砌砖头,只要我们不关心盖楼的原因.建筑的原理.土木工程基础和工程经验,就算我们砌了100栋高楼,我们也就只是一个砌砖工人,永远也成为不了一个工程师,更别说建筑师了.而那些包工头也只 ...
- SQL Agent服务无法启动如何破
问题现象 从阿里云上镜像过来的一台的数据库服务器,SQL Agent服务启动不了,提示服务启动后停止.(原数据库服务器是正常的,怀疑跟镜像有关) 如下是系统日志和SQL Agent的日志 SQLSer ...
- php性能优化
序 很长时间没有写博文了,最近换了工作,长时间加班,根本没有时间做其他事情!今天闲下来了,想一想php性能方面的事情.这也是我2014年的第一篇博文! 推荐阅读:初学者到中级者应该掌握的! p ...
- 推荐两款简单好用的图片放大jquery插件
一.zoomfiy.js 推荐可以从这里下载 使用说明: 使用该jquery 插件引入该插件的js:zoomfiy.js 或 min引入该插件的css:zoomfiy.css 或 min前后顺序都可j ...
- easyui 数据库修改部分(基于数据添加逻辑功能修改)
{iconCls:'icon-edit',text:'修改', handler:function(){ type="edit"; //判断是否选中一条数据 var data = $ ...
- 【.NET深呼吸】线程信号量(Semaphore)
Semaphore类可以控制某个资源允许访问的线程数,Semaphore有命名式的,也有不命名的:如果不考虑跨进程工作,一般在代码中使用不命名方式即可. 信号量有点类似于等待句柄,某个线程如果调用了W ...
- Sublime文件夹显示过滤
Preferences/Setting-User添加如下命令: "file_exclude_patterns": ["*.mate", "*.gif& ...