本文链接http://www.cnblogs.com/Bond/p/4178311.html

jquery document  ready的实现其很很简,虽说简单,其很很多人还是没去关注过它的实现。我现在闲来无事就闲扯一下jquery document  ready的实现。在低版本1.XX的实现和2.XX的略有不同,这里以2.1.1为准

平时一般都会这样写,一般就这两种方式

$(document).ready(function(){
//do something
})
$(function(){
//do something
})

分析源码发现其实以上两种写法是一样的效果,所以推荐使用第二组写法,更为简洁。

发现最后都是$(document).ready(),为了找到实现,我们就要找到JQuery.fn.ready的实现,于是我们找到了这小段

不难发现最后都是调用了jQuery.ready.promise().done( fn );

显然这里得找到jQuery.ready.promise,其实jQuery.ready.promise()返回了一个promise对象然后done(fn) 其实就是向里面添加回调函数,最终也是调用的Callback的add,

根据上面的推测我们找到了一下这段代码实现

调用jQuery.ready.promise(),进入函数判断readyList是否已经存在,不存在就创建一个deferred对象赋给readyList,此时readyList就是一个Deferred实例对象

往下判断document.readyState === "complete"  如果未true 就执行setTimeout( jQuery.ready ); 稍后分析jQuery.ready这个挂在到JQuery上的静态方法

下面就是给document 和window分别添加相应的事件和回调,由于这里只支持高级浏览器,所以简化了很多只有两句话

document.addEventListener( "DOMContentLoaded", completed, false );

window.addEventListener( "load", completed, false );

最终返回return readyList.promise( obj ),所有的DOM ready 的回调都添加到了readyList上面; 这里依赖了JQuery Deferred模块,JQuery Deferred又依赖于Callback. 有兴趣可以去看看它们的实现,还是很有技巧性的,值得一看,这里就不扯那个,一扯就停不下来了。

其实就是返回deferred.promise(obj) ,通过 deferred.promise() 方法返回的 deferred promise 对象,是没有 resolve ,reject, progress , resolveWith, rejectWith , progressWith 这些可以改变状态的方法,你只能使用 done, then ,fail 等方法添加 handler 或者判断状态。

这里我们发现最终当DOMContentLoaded 会执行completed 其实completed 最后也是执行jQuery.ready();

最后我们只需要扒开jQuery.ready神秘的面纱,dom ready的最后的实现就迎刃而解了。

于是我们又找到了这段代码

以下简单分析一下它的实现

前面直接调用jQuery.ready(),进入这个函数后第一个判断为false,往下走jQuery.isReady = true; 标记isReady =true, 第二个if也直接跳过,最后执行readyList.resolveWith( document, [ jQuery ] );

这句话是最后的核心,readyList之前被赋值为了Deferred对象的一个实例,这里执行resolveWith() 这里简单说下,resolveWith内部其实就是 jQuery.Callbacks("once memory"),然后resolveWith就是fireWith

知道最后调用的上下文和参数,最终执行之前添加到readyList里面的所有回调。

readyList内部的

[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],

[ "notify", "progress", jQuery.Callbacks("memory") ]

其它的都忽略 只关注这个jQuery.Callbacks("once memory")

我们所有的$(fn) fn都是加到了 jQuery.Callbacks("once memory") 里面,一旦执行过一次fire第二次调用fire就不会有作用,如果调用过fire在add(fn) 这个fn会立即执行。

所以:document ready只会执行一次,一旦执行过在再次$(fn)此时 fn会立即执行。

一个简单的document ready jqeury的实现还是比较绕的,内部依赖了Deferred, 不清楚Deferred的人看来会感觉晕晕的,其实我们可以抛开Deferred 再来看就会觉得简单许多。

jquery dom ready, jqery2.1.1实现-源码分析的更多相关文章

  1. jQuery原型属性constructor,selector,length,jquery和原型方法size,get,toArray源码分析

    首先看一下在jQuery1.7.1中定义的原型属性和方法有哪些? init方法作为实际的构造函数已经详细分析过了,需要了解可以参考http://www.cnblogs.com/yy-hh/p/4492 ...

  2. jQuery原型方法first,last,eq,slice源码分析

    这4个方法中前3个方法很常用大家都见过,但是slice方法可能会以为是数组方法,其实slice也是jQuery的一个原型方法,只不过是底层方法是为其他方法服务的(更具体点是为eq方法服务的),首先还是 ...

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

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

  4. jQuery.access源码分析

    基本理解 jQuery.attr是jQuery.attr,jQuery.prop,jQuery.css提供底层支持,jQuery里一个比较有特色的地方就是函数的重载, 比如attr,有如下几种重载 $ ...

  5. jQuery-1.9.1源码分析系列完毕目录整理

    jQuery 1.9.1源码分析已经完毕.目录如下 jQuery-1.9.1源码分析系列(一)整体架构 jQuery-1.9.1源码分析系列(一)整体架构续 jQuery-1.9.1源码分析系列(二) ...

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

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

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

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

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

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

  9. [转]jQuery DOM Ready

    一直以来,各种JS最佳实践都会告诉我们,将JS放在HTML的最后,即</body>之前,理由就是:JS会阻塞下载,而且,在JS中很有可能有对DOM的操作,放在HTML的最后,可以尽可能的保 ...

随机推荐

  1. 使用VERT.X构建分布式企业级应用

    谈到企业应用,就得谈分布式.低耦合.模块化.面向服务.可扩展性等等.早些时候的技术有CORBA和EJB,后面兴起的有WebService和MDB.但是这些技术不是学习.开发门槛高就是不那么轻量化.我现 ...

  2. 阻止子View获取焦点方法

    android:descendantFocusability:ViewGroup ep: android:descendantFocusability=blocksDescendants

  3. C# 打印文件

    这几天做的功能用到了打印这个功能,直接在网上找了点demo,在这里做个备份. 1.直接打印DataTable using System; using System.Collections.Generi ...

  4. IOS- 最简单的反向传值- block

    block 常用于反向传值 声明 返回值类型 (^block)(参数列表) 调用 闭包的名字=^(参数列表){}: 闭包的名字(): 如: void(^aaaaa)(int num,NSString ...

  5. 中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030

    中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030 内容详见: http://www.360doc.com/content/11/1004/12/6139921_1 ...

  6. JS原型与原型链终极详解(转)

    JavaScript原型及原型链详解 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object,Function 是JS自带的函数对象. ...

  7. 问题解决:form表单的button按钮问题

    最近写了一个KendoUI 的kendowindow组件,组件里包含了一个form表单,表单里有一个button,不是提交保存的按钮,而是链接到另一个kendowindow的按钮,跟请求提交毫无关系, ...

  8. ESP8266开发课堂之 - 建立一个新项目

    项目架构 ESP8266项目开发并非使用IDE自动管理工程文件,而是使用了诸多第三方程序如Python,以及使用了Makefile管理依赖与控制编译,所以项目的创建与日常维护较为复杂,本篇将详述创建一 ...

  9. PHPEXCEL使用实例

    最近在项目中要用到PHP生成EXCEL,上网找了一下,发现PHPEXCEL挺不错,用了一下,感觉还行,就是设置单元格格式的时候比较麻烦,总体来说功能还是比较强大的,还有生成PDF什么的,发一个实例吧 ...

  10. MFC GDI相关对象

    首先说明几个名词: CDC 是MFC对Wind32 API的设备上下文(DC)进行封装的C++类,由他继承的类包括 CPaintDC(常用)CWindowDC(现在软件基本不用) CClientDC( ...