只要使用过jQuery的,想必对ready都不陌生,$(function(){})和$(document).ready(function(){})的使用更是习以为常。

要说到window.onload与document.ready的区别也能谈出个一二,最重要的区别就是:

window.onload是在dom文档树以及所有文件都加载完成后,才执行;

而document.ready是,只要dom文档树加载完,就执行,且当dom文档树加载完就执行的好处就是,当页面中的图片等外部资源过多时,window.onload迟迟不能触发,这时若还没有绑定事件,用户点击按钮时没有反应,这不影响用户体验么。

咦,Jquery的ready这么牛逼,那Jquery是怎么实现ready这个函数的呢?我们不妨一起来探究探究。

以下Jquery.ready的源码,截自于jQuery 1.12.0

 jQuery.ready.promise = function( obj ) {
if ( !readyList ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called
// after the browser event has already occurred.
// we once tried to use readyState "interactive" here,
// but it caused issues like the one
// discovered by ChrisS here:
// http://bugs.jquery.com/ticket/12282#comment:15
if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready
window.setTimeout( jQuery.ready ); // Standards-based browsers support DOMContentLoaded
} else if ( document.addEventListener ) { // Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work
window.addEventListener( "load", completed ); // If IE event model is used
} else { // Ensure firing before onload, maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work
window.attachEvent( "onload", completed ); // If IE and not a frame
// continually check to see if the document is ready
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 window.setTimeout( doScrollCheck, 50 );
} // detach all dom ready events
detach(); // and execute any waiting functions
jQuery.ready();
}
} )();
}
}
}
return readyList.promise( obj );
};

从上面的源码中,可以看出,jQuery.ready主要通过以下几个东东来判断dom文档树是否加载完成:

(1)  document.readyState

(2)  DOMContentLoaded

(3)  onreadystatechange

(4)  doScroll

下面,我们就一步一步来解析

1、  document.readyState

readyState是个什么东东呢?它是document的一个属性值,返回当前文档的状态,该属性会根据文档加载情况,返回如下几个属性值:

属性值

意义

uninitialized

还未开始载入

loading

载入中

interactive

已加载,文档与用户可以开始交互

complete

载入完成

从属性值,可得知,倘若当我们判断document.readyState为complete,那么DOM文档树就是加载完毕。但,从上面源码注释(6--11行)中可以得知ChrisS发现了一个很特别的问题,所以我们在判断document.readyState === ‘complete’后,执行jQuery.ready,需要延迟一下。但上面的代码中,怎么没有延迟时间呢?

那是因为倘若我们没有设置延迟时间,setTimeout就会根据当前浏览器及操作系统,自动给它设定一个最小延迟时间。在《JavaScript忍者的秘密》中曾提到:

2、  DOMContentLoaded事件

从上面的源代码注释中,可以看出DOMContentLoaded是基于标准的浏览器的。

那么它的作用是什么呢?

当DOM文档树加载完成后,即触发。

所以可以在标准的浏览器中判断DOMContentLoaded,来判断DOM树,是否加载完成。

3、  onreadystatechange事件

上面的DOMContentLoaded事件是基于标准的浏览器的,那倘若不标准的呢,如IE,则使用onreadystatechange事件。

咦,怎么感觉如此熟悉。

XMLHttpRequest—>Ajax。想起来了么。在IE中onreadystatechange是私有化的,即所有元素都存在onreadystatechange事件,而W3C标准中,仅XMLHttpRequest对象中存在onreadystatechange事件。所以当事件触发时,倘若onreadystatechange === complete,则可视为DOM树加载完成。

4、  doScroll

从上面的源码中的注释(49--50行),可得,Diego Perini报告一种检测IE下DOM文档是否加载完成的方法,即,使用doScroll。

咦,上面onreadystatechange事件,不是能处理了吗?!!

是的,但是它有个弊端,就是当页面中存在图片时,可能反而会晚于onload事件后,触发。

为什么呢?

因为我们是依据onreadystatechange === complete来判断的嘛,如果图片没加载或者正在加载中,那么onreadystatechange就不等于complete了哦。

所以为了保险起见,再用doScroll来检测。

doScroll的原理就是,当页面DOM未加载完成时,调用doScroll方法,会产生异常。所以利用try-catch来对doScroll捕获异常就可以判断DOM文档是否加载完咯。

好了,jQuery.ready的源码就解析到这儿,纯属自己观点,有什么不对,请狠狠拍砖且交流,谢谢。

jQuery之ready源码分析的更多相关文章

  1. Jquery之isPlainObject源码分析

    今天对Jquery中 isPlainObject 源码分析. 1.  isPlainObject 方法的作用: 用来判断传入参数,是否是对象. 2. 源码分析:isPlainObject: funct ...

  2. jQuery.clean()方法源码分析(一)

    在jQuery 1.7.1中调用jQuery.clean()方法的地方有三处,第一次就是在我之前的随笔分析jQuery.buildFramgment()方法里面的,其实还是构造函数的一部分,在处理诸如 ...

  3. jQuery实现jsonp源码分析(京东2015面试)

    // Bind script tag hack transportjQuery.ajaxTransport( "script", function(s) { // This tra ...

  4. jQuery 2.0.3 源码分析 事件绑定 - bind/live/delegate/on

    事件(Event)是JavaScript应用跳动的心脏,通过使用JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应 事件的基础就不重复讲解了,本来是定位源码分析 ...

  5. jQuery1.9.1源码分析--数据缓存Data模块

    jQuery1.9.1源码分析--数据缓存Data模块 阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(el ...

  6. jQuery 源码分析(十八) ready事件详解

    ready事件是当DOM文档树加载完成后执行一个函数(不包含图片,css等),因此它的触发要早于load事件.用法: $(document).ready(fun) ;fun是一个函数,这样当DOM树加 ...

  7. jQuery实现DOM加载方法源码分析

    传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... }  但 ...

  8. jQuery-1.9.1源码分析系列(二)jQuery选择器

    1.选择器结构 jQuery的选择器根据源码可以分为几块 init: function( selector, context, rootjQuery ) { ... // HANDLE: $(&quo ...

  9. angular源码分析:angular中jqLite的实现——你可以丢掉jQuery了

    一.从function JQLite(element)函数开始. function JQLite(element) { if (element instanceof JQLite) { //情况1 r ...

随机推荐

  1. 有关iOS系统中调用相机设备实现二维码扫描功能的注意点(3/3)

    今天我们接着聊聊iOS系统实现二维码扫描的其他注意点. 大家还记得前面我们用到的输出数据的类对象吗?AVCaptureMetadataOutput,就是它!如果我们需要实现目前主流APP扫描二维码的功 ...

  2. css实现一行文字居中,多行文字居左

    第一种方法: <style> *{margin:0;padding:0;} .box{width:500px;height:300px;border:1px solid #000;text ...

  3. 编写base64图片文件

    base64编码代替css背景图片在网站上应用是很广泛的,例如:loading gif图片,天猫加载时那只猫等等. 因为base64图片可以减少http请求,所以我们经常会把不经常改动的,独立的,尺寸 ...

  4. 也来说说关于未在本地计算机上注册“VFPOLEDB.1”的程序的解决方法

    大家都知道VFP是一个非常古老的数据库.但是,还有一些单位用到这些数据库. 前段时间,也做了一个关于DBF数据导出的功能的测试.程序以前有同事写好了,但当我进行修改调试的时候,问题就出来了. 调试的时 ...

  5. openGL实现二维图形和三维图形

    openGL是一个强大的底层图形库,其命令最初的时候使用C语言实现的.openGL定义了一个图形程序接口,常用于制作处理三维图像,功能强大,调用方便,在图像处理十分受欢迎. 实现图形主要使用的是ope ...

  6. Jenkins 集成打包和上传 App Store 的冲突

    周一下午用 Jenkins 集成打包,遇到了一个很奇怪的问题,之前上传到 APP Store 的时候 Build Settings->“Code Signing Resource Rules P ...

  7. HDU--航海舰队

    海舰队 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  8. HDU---BigZhuGod的粉丝

    Problem Description 真正的粉丝,是不需要题目描述的^_^.   Input 第一行输入数据组数T(1≤T≤100).接下来T行,每行一个有格式的字符串,详见样例,字符串长度不超过1 ...

  9. CF2.D 并查集+背包

    D. Arpa's weak amphitheater and Mehrdad's valuable Hoses time limit per test 1 second memory limit p ...

  10. js 预处理用户上传图片

    前几个月闲得无聊写得一段代码,没想最近刚好用上了,在硬盘里翻了半天找回来,还没好好整理直接用上了手机用户拍照上传的图片一般都在1M 到4M 之间,如果只是用作头像尺寸就可以缩小很多,1M甚至几M的图转 ...