星空网 > 软件开发 > Java

jQuery之ready源码分析

只要使用过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。

 1 jQuery.ready.promise = function( obj ) { 2   if ( !readyList ) { 3  4     readyList = jQuery.Deferred(); 5  6     // Catch cases where $(document).ready() is called 7     // after the browser event has already occurred. 8     // we once tried to use readyState "interactive" here, 9     // but it caused issues like the one10     // discovered by ChrisS here:11     // http://bugs.jquery.com/ticket/12282#comment:1512     if ( document.readyState === "complete" ) {13 14       // Handle it asynchronously to allow scripts the opportunity to delay ready15       window.setTimeout( jQuery.ready );16 17     // Standards-based browsers support DOMContentLoaded18     } else if ( document.addEventListener ) {19 20       // Use the handy event callback21       document.addEventListener( "DOMContentLoaded", completed );22 23       // A fallback to window.onload, that will always work24       window.addEventListener( "load", completed );25 26     // If IE event model is used27     } else {28 29       // Ensure firing before onload, maybe late but safe also for iframes30       document.attachEvent( "onreadystatechange", completed );31 32       // A fallback to window.onload, that will always work33       window.attachEvent( "onload", completed );34 35       // If IE and not a frame36       // continually check to see if the document is ready37       var top = false;38 39       try {40         top = window.frameElement == null && document.documentElement;41       } catch ( e ) {}42 43       if ( top && top.doScroll ) {44         ( function doScrollCheck() {45           if ( !jQuery.isReady ) {46 47             try {48 49               // Use the trick by Diego Perini50               // http://javascript.nwbox.com/IEContentLoaded/51               top.doScroll( "left" );52             } catch ( e ) {53               return window.setTimeout( doScrollCheck, 50 );54             }55 56             // detach all dom ready events57             detach();58 59             // and execute any waiting functions60             jQuery.ready();61           }62         } )();63       }64     }65   }66   return readyList.promise( obj );67 };

从上面的源码中,可以看出,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忍者的秘密》中曾提到:

jQuery之ready源码分析 

2、  DOMContentLoaded事件

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

那么它的作用是什么呢?

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

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

3、  onreadystatechange事件

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

咦,怎么感觉如此熟悉。

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源码分析

关键词:jquery

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

德国fba费用:https://www.goluckyvip.com/tag/30037.html
德国fba海派:https://www.goluckyvip.com/tag/30038.html
德国fba海外仓:https://www.goluckyvip.com/tag/30039.html
跨境新手:https://www.goluckyvip.com/tag/3004.html
德国fba海运:https://www.goluckyvip.com/tag/30040.html
德国fba换标:https://www.goluckyvip.com/tag/30041.html
武陵山大裂谷周围景点 武陵山大裂谷周围景点图片:https://www.vstour.cn/a/411233.html
南美旅游报价(探索南美洲的旅行费用):https://www.vstour.cn/a/411234.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流