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 ...
随机推荐
- 在手机网页上模拟 js 控制台
在手机上模拟 console 做一些简单代码调试 在工作机上编辑好代码用QQ 之类的工具传到 手机上在调试当然你也可以尝试用一只手指写代码的壮举设置 window.console = mobiDeb ...
- .NET面试题系列[13] - LINQ to Object
.NET面试题系列目录 名言警句 "C# 3.0所有特性的提出都是更好地为LINQ服务的" - Learning Hard LINQ是Language Integrated Que ...
- chunkupload 文件上传断点续传组件(java) - 正式发布
chunkupload简介 chunkupload是一款基于java语言的断点续传组件,针对文件上传,非文件下载,集成方便,使用简单. chunkupload实现如下功能: · 实现断点续传 · ...
- CSharpGL(6)在OpenGL中绘制UI元素
CSharpGL(6)在OpenGL中绘制UI元素 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入 ...
- HTML中em与b等的区别
最近在学习HTML基本知识,看到b标签和strong还有em,都是表示强调目的的,那他们之间的区别是什么呢?总结如下: < b > < i > 是视觉要素(presentati ...
- C# BS消息推送 SignalR Hubs环境搭建与开发(二)
1. 前言 本文是根据网上前人的总结得出的. 环境: SignalR2.x,VS2015,Win10 2. 开始开发 1)新建一个MVC项目,叫做SignalRDemo 2)安装SignalR包 In ...
- WaitType:CXPACKET
CXPACKET 等待类型是SQL Server 并发执行一个query时产生的.在run一个big query时,SQL Server充分利用系统的所有资源(CPU,Memory,IO),在最短时间 ...
- EF-InvalidOperation系列
1.InvalidOperation强制转换为值类型 'System.Guid' 失败,因为实例化的值为 null.结果类型的泛型参数或查询必须使用可以为 null 的类型 错误信息: The cas ...
- 【转】WPF 单选的Checkbox
今天同事要在DataGrid里用单选的Checkbox,我感觉很多余,因为正常DataGrid就可以单选,为什么还要加一列Checkbox,但是人家要求再那里,我就告诉他,可以用RadioButton ...
- 虚拟文件系统(VFS)
原文链接:http://www.orlion.ga/1008/ linux在不同的文件系统之上做了一个抽象层,使得文件.目录.读写访问等概念都成为抽象层概念,这个抽象层被称为虚拟文件系统(VFS). ...