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"); } }, ...