jQuery 通过extend将方法 扩展到jQuery 函数上
jQuery.extend({
expando: 生成唯一的jQuery字符串 (jQuery 内部使用)
noConflict: 防止冲突函数,
//后面四个都与DOM加载有关
isReady: DOM是否加载完(内),
readyWait: 等待多少文件的计数器(内),
holdReady: 推迟DOM触发,
ready: 准备DOM触发,
...
})
expando() 属性:
因为生成的字符串具有唯一性,后续的 数据缓存、事件操作、ajax 都用到了它。
jQuery.extend({
expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
...
})
noConflict() 方法: 这里 有介绍。
下面介绍jQuery的DOM加载相关:
window.onload 和 $(function(){ ...}) 的区别在于:
前者是等页面元素都加载完,后者是只等DOM节点加载完(加载速度高于前者,jQuery中利用了js原生方法 DOMContentLoaded 实现)。
jQuery中调用原理见下图:
由上图看出:接下来只分析 jQuery.ready.promise().done( fn )就可以了。
由jQuery.ready.promise().done( fn ),可猜想 jQuery.ready.promise() 返回的是deferred延迟对象,后面才能直接跟 .done() 。(查看 deferre对象介绍 )
jQuery.ready.promise() 相关源码:
...
var readyList;
...
completed = function() {
document.removeEventListener( "DOMContentLoaded", completed, false );
window.removeEventListener( "load", completed, false );
jQuery.ready();
};
...
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
readyList = jQuery.Deferred();
if ( document.readyState === "complete" ) {
setTimeout( jQuery.ready );
} else {
document.addEventListener( "DOMContentLoaded", completed, false );
window.addEventListener( "load", completed, false );
}
}
return readyList.promise( obj );
};
由上面代码可以看出:
1、jQuery.ready.promise()中创建了延迟对象readyList,最后返回的是readyList.promise() (不允许外部修改状态的延迟对象);
2、不管走if还是else中的completed方法,最终调用的都是$.ready() 方法。
$.ready()相关源码:
...
isReady: false,
readyWait: 1,
holdReady: function( hold ) {
if ( hold ) {
//readyWait就是一个计数器,表示还有多少个条目就绪后事件才能执行
jQuery.readyWait++;
} else {
jQuery.ready( true );
}
},
ready: function( wait ) {
// 如果还有等待的事件的话就取消执行,直接返回
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;
}
jQuery.isReady = true;
// 如果正常的ready事件触发, 减少等待的数目,然后继续等待
if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
readyList.resolveWith( document, [ jQuery ] );
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
}
},
...