jquery源码解析:expando,holdReady,ready详解
jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的。
jQuery.extend({ //当只有一个对象时,就把这个对象中的属性和方法扩展到this对象中,这里的this指向jQuery
expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
//唯一性,core_version 为jQuery的版本号。\D的意思是:不是数字的,就选中。因此expando就是jQuery+一段整数。数据缓存,ajax,事件机制都用到了这个。
noConflict: function( deep ) {
//处理冲突,因为有些库可能会用到$甚至jQuery,这时就可以调用chaojidan = $.onConflict(true);这时chaoijdan就可以当做jQuery了,并且其他库可以使用$标识了
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
},
isReady: false,
readyWait: 1,
holdReady: function( hold ) {
if ( hold ) {
jQuery.readyWait++;
} else {
jQuery.ready( true );
}
},
ready: function( wait ) {
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;
}
jQuery.isReady = true;
if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
readyList.resolveWith( document, [ jQuery ] );
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
}
},
//以上几个属性和方法其实就是解决DOM加载问题的,大家都知道onload是等DOM树建造完成,并且资源加载完成才会触发。但是我们只需要DOM树构造完成,就执行绑定事件,所以有一个DOMContentLoaded事件。但是低版本浏览器不支持,所以需要兼容,jQuery就写了兼容方法。所以在这里介绍一下它是怎么处理的。
$(function(){}) -> $(document).ready(function(){}) -> $().ready() -> jQuery.ready.promise().done(fn),
jQuery.ready.promise = function( obj ) {
if ( !readyList ) { //第一次调用时,为空,所以进入。之后就直接使用这个对象
readyList = jQuery.Deferred(); //新建一个延迟对象
if ( document.readyState === "complete" ) {
//DOM已经加载结束了,这时就可以直接调用jQuery.ready,不用再绑定事件了
setTimeout( jQuery.ready );
//DOM快加载好的时候,IE的readyState有可能就是complete了,这时调用jQuery.ready会出问题,因此延迟调用,确保IE下也没问题。
} else {
document.addEventListener( "DOMContentLoaded", completed, false );
window.addEventListener( "load", completed, false );
//火狐浏览器可能会缓存onload事件,这时onload会先于DOMContentLoaded触发。写两个,更保险
}
}
return readyList.promise( obj ); //延迟对象的状态有几种,在外面可以被修改,但是promise不能修改
};
completed = function() {
document.removeEventListener( "DOMContentLoaded", completed, false ); //只调用一次completed 方法
window.removeEventListener( "load", completed, false );
jQuery.ready();
};
//jQuery.ready.promise().done(fn) (延迟对象调用done方法,把fn方法加入延迟对象,当触发延迟对象的resolveWith时,就会执行fn方法) -> jQuery.ready() -> readyList.resolveWith( document, [ jQuery ] )
ready: function( wait ) {
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;
}
jQuery.isReady = true; //只触发一次
if ( wait !== true && --jQuery.readyWait > 0 ) { //DOM的ready正常触发时,也要检查是否需要等待
return;
}
readyList.resolveWith( document, [ jQuery ] );
//第一个参数是指向this(回调方法的执行上下文),第二个参数是传给回调方法的参数。这个回调方法,就是通过延迟对象的done方法加进来的fn.因此,resolveWith( document, [ jQuery ] );相当于fn(jQuery),在document中执行。
if ( jQuery.fn.trigger ) { //这里处理jQuery第三种DOM加载完成执行js的方式。
jQuery( document ).trigger("ready").off("ready"); //触发ready事件后,马上移除掉,只触发一次。
//$(document).on("ready",function(){}),通过document绑定ready事件来实现。
}
},
holdReady: function( hold ) { //阻止Dom加载完成执行function,$.holdReady(true),
if ( hold ) {
jQuery.readyWait++; //要加载多个文件时(a.js,b.js),就要每次都++。
} else {
jQuery.ready( true ); //$.holdReady(false),恢复执行,减少一次jQuery.readyWait,直到它为0.
}
},
这个方法有什么用呢?举个例子:$.getScript("a.js",function(){}); $(function(){ a.say(); });这个代码的意思是加载完a.js,然后再调用a的say 方法。但是a.js需要下载,所以执行a.say会报错。这时,可以先$.holdReady(true),这样$(function(){ a.say(); }中的a.say(); 就不会执行了。直到我在$.getScript("a.js",function(){$.holdReady(false)});才可以执行。而这时,a.js加载完成,并执行结束后,调用回调方法,执行$.holdReady(false),恢复执行。
isFunction: function( obj ) { //在低版本IE浏览器下typeof alert 返回object,而不是function
return jQuery.type(obj) === "function";
},
isArray: Array.isArray, //不兼容IE8以及以下版本
isWindow: function( obj ) {
return obj != null && obj === obj.window;
//false == null -> false ,true == null -> false。只有null和undefined才等于null,而只有这两个变量没有属性。其他的像字符串有包装对象,可以有属性。window有两种意思:(1)全局对象,(2)浏览器窗口。而只有window才有window属性,因此只有window才会返回true.window.window表示全局对象中的浏览器窗口。
},
isNumeric: function( obj ) { //typeof NaN -> number
return !isNaN( parseFloat(obj) ) && isFinite( obj ); //Number.MAX_VALUE最大值,加1就会是无限大,就不是number类型
//先判断参数是否能转成数字,不可以就是NaN,那么isNaN就会返回true。如果是数字,但是必须是有限数,不然也不是number类型。
},
...
})
加油!
jquery源码解析:expando,holdReady,ready详解的更多相关文章
- jQuery 源码解析(三) pushStack方法 详解
该函数用于创建一个新的jQuery对象,然后将一个DOM元素集合加入到jQuery栈中,最后返回该jQuery对象,有三个参数,如下: elems Array类型 将要压入 jQuery 栈的数组元素 ...
- guava-retrying 源码解析(停止策略详解)
一.停止策略相关类 1.停止策略接口:StopStrategy接口,只有一个抽象方法 // 是否应该停止重试.不同的停止策略有不同的实现.boolean shouldStop(Attempt fail ...
- guava-retrying 源码解析(等待策略详解)
一.等待策略相关类: 1.等待策略接口:WaitStrategy接口 该接口只有一个方法,就是返回尝试失败之后,下一次尝试之前的等待时间.long computeSleepTime(Attempt f ...
- vuex 源码解析(三) getter属性详解
有时候我们需要从store中的state中派生出一些状态,例如: <div id="app"> <p>{{reverseMessage}}</p> ...
- guava-retrying 源码解析(阻塞策略详解)
这是一种策略,用于决定重试者应如何在重试尝试之间进行阻止.通常这只是一个thread.sleep(),但是如果需要的话,实现可能更复杂. 一.阻塞策略相关的类或接口 1.阻塞策略接口:BlockStr ...
- JQuery源码解析(一)
写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...
- jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
- jquery源码解析:代码结构分析
本系列是针对jquery2.0.3版本进行的讲解.此版本不支持IE8及以下版本. (function(){ (21, 94) 定义了一些变量和函数, jQuery = function() ...
- jquery源码解析:jQuery数据缓存机制详解1
jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...
- jquery源码解析:addClass,toggleClass,hasClass详解
这一课,我们将继续讲解jQuery对元素属性操作的方法. 首先,我们先看一下这几个方法是如何使用的: $("#div1").addClass("box1 box2&quo ...
随机推荐
- Java网络编程小结 URLConnection协议处理器
URL和URLConnection类 网络中的URL(Uniform Resource Locator)是统一资源定位符的简称.它表示Internet上某一资源的地址.通过URL我们可以访问Inter ...
- 【BZOJ3926】诸神眷顾的幻想乡 【广义后缀自动机】
题意 给定一棵树,每个结点有一个颜色,问树上有多少种子串(定义子串为两点上路径颜色的序列).保证叶子结点<=20 分析 我们可以发现一个结论,任意一个子串一定是以某个叶子结点为根的trie的后缀 ...
- DBArtist之Oracle入门第2步: 了解Oracle的Database Control
之前安装好数据库后,会有下面这个弹窗,然后根据Database Control URL地址进入瞧一瞧,看一看! 根据地址进入以后,是一个登录界面,用system账户登录,密码就是安装Oracle的时候 ...
- Computer2
luo@luo-All-Series:~/MyFile/TensorflowProject$ conda create -n flappbird1 python=3.7Solving environm ...
- 801. Minimum Swaps To Make Sequences Increasing 为使两个数组严格递增,所需要的最小交换次数
[抄题]: We have two integer sequences A and B of the same non-zero length. We are allowed to swap elem ...
- centos 6.5 部署openvpn 2.4
软件下载地址 软件下载地址 https://openvpn.net/index.php/open-source/downloads.html 服务端 源Tarball(gzip) https://sw ...
- 抓包工具Fidder移动端HTTP请求抓包详解
第一步:下载神器Fiddler,下载链接: http://fiddler2.com/get-fiddler 下载完成之后,傻瓜式的安装一下了! 第二步:设置Fiddler打开Fiddler, ...
- 9个使用前必须再三小心的 Linux 命令-乾颐堂
Linux shell/terminal 命令非常强大,即使一个简单的命令就可能导致文件夹.文件或者路径文件夹等被删除. 在一些情况下,Linux 甚至不会询问你而直接执行命令,导致你丢失各种数据信息 ...
- mongodb 更新操作
db.aaaa.update({},{$push:{money:{$each:[8,9,10],$slice:-4}}}) db.aaaa.update({},{$addToSet:{money:{$ ...
- cenots7单机安装Kubernetes
关于什么是Kubernetes请看另一篇内容:http://www.cnblogs.com/boshen-hzb/p/6482734.html 一.环境搭建 master安装的组件有: docker ...