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。
- 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源码分析的更多相关文章
- Jquery之isPlainObject源码分析
今天对Jquery中 isPlainObject 源码分析. 1. isPlainObject 方法的作用: 用来判断传入参数,是否是对象. 2. 源码分析:isPlainObject: funct ...
- jQuery.clean()方法源码分析(一)
在jQuery 1.7.1中调用jQuery.clean()方法的地方有三处,第一次就是在我之前的随笔分析jQuery.buildFramgment()方法里面的,其实还是构造函数的一部分,在处理诸如 ...
- jQuery实现jsonp源码分析(京东2015面试)
// Bind script tag hack transportjQuery.ajaxTransport( "script", function(s) { // This tra ...
- jQuery 2.0.3 源码分析 事件绑定 - bind/live/delegate/on
事件(Event)是JavaScript应用跳动的心脏,通过使用JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应 事件的基础就不重复讲解了,本来是定位源码分析 ...
- jQuery1.9.1源码分析--数据缓存Data模块
jQuery1.9.1源码分析--数据缓存Data模块 阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(el ...
- jQuery 源码分析(十八) ready事件详解
ready事件是当DOM文档树加载完成后执行一个函数(不包含图片,css等),因此它的触发要早于load事件.用法: $(document).ready(fun) ;fun是一个函数,这样当DOM树加 ...
- jQuery实现DOM加载方法源码分析
传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... } 但 ...
- jQuery-1.9.1源码分析系列(二)jQuery选择器
1.选择器结构 jQuery的选择器根据源码可以分为几块 init: function( selector, context, rootjQuery ) { ... // HANDLE: $(&quo ...
- angular源码分析:angular中jqLite的实现——你可以丢掉jQuery了
一.从function JQLite(element)函数开始. function JQLite(element) { if (element instanceof JQLite) { //情况1 r ...
随机推荐
- 关于C#开发WEB项目TextBox控件的自适应高问题解决办法!
前两天做WEB开发时候遇到了一个小问题TextBox 控件要根据输入的内容多少自动改变大小,并且这个大小要求是在本页面内最大化.也就是 Width="100%" Height=&q ...
- C# SQL 面试题自我总结
1,asp.net单点登录机制 2,多线程同步机制 3,写一个冒泡排序算法 4,写一个递归算法 5,字符串反转 字符串分隔后调用reverse 方法. 6,sql 中ID自动增长,查询31到40条记录 ...
- MongoDB常用操作命令大全
成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作.输入help可以看到基本操作命令,只是MongoDB没有创建数据库的命令,但有类似的命令 如:如果你想创建一个 ...
- java空指针异常:java.lang.NullPointException
一.什么是java空指针异常 我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析.空 ...
- java分享第十五天(log4j 格式详解)
log4j 格式详解 log4j.rootLogger=日志级别,appender1, appender2, -. 日志级别:ALL<DEBUG<INFO<WARN<ERRO ...
- jsp 中 有没有类似java if else语句
<c:when test=""></c:when> <c:otherwise></c:otherwise> 有if else的功能 ...
- win32进程名查找进程PID
1. #include <Psapi.h> #pragma comment(lib, "Psapi.lib") DWORD GetProcIDFromName(LPCT ...
- 最小生成树 prime + 队列优化
存图方式 最小生成树prime+队列优化 优化后时间复杂度是O(m*lgm) m为边数 优化后简直神速,应该说对于绝大多数的题目来说都够用了 具体有多快呢 请参照这篇博客:堆排序 Heapsort / ...
- python 之 Django 基础篇
1,Django流程介绍 MTV模式 著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据 ...
- Allegro之Win7下不能实时刷新操作显示的问题
Allegro软件主界面下: setup-> user preferences-> display->opengl中选定disable_opengl,即关掉OpenGL后,再重新启动 ...