jQuery(事件-页面事件ready(fn)) 3.0
1.用法$(document).ready(function(){console.log(document.readyState)//interactive--完全加载(completed)前面一个状态可以和页面的DOM元素交互;})
1.1、普通用法:页面解析是从上到下依次解析;所以console.log(document.readyState)//loading;
1.2、用window.onload=function(){console.log(document.readyState//completed//完全加载完,)}
1.3、从上面可以看出普通用法,不是你想操作页面DOM元素就可以操作,必须要在DOM元素加载后面才可以操作。jQuery的页面加载事件比window的加载事件执行时间要快。这也是节约了响应时间。
2.解析:
2.1、因为是元素的选择,所以进入jQuery走的是原型链上的方法,
new jQuery.fn.init();
然后返回jQuery.fn.init[1],在init里面找到ready方法;
2.2、执行jQuery.fn.ready=function(fn){jQuery.ready.romise().done(fn)}
var tuples = [
[ "notify", "progress", jQuery.Callbacks( "memory" ),jQuery.Callbacks( "memory" ), 2 ],
[ "resolve",done",jQuery.Callbacks( "once memory" ),jQuery.Callbacks( "once memory" ), 0, "resolved" ],
[ "reject", "fail", jQuery.Callbacks( "once memory" ),jQuery.Callbacks( "once memory" ), 1, "rejected" ]
]
通过jQuery.each()方法,把done放到了promise={}。
var list = tuple[ 2 ],//list=jQuery.Callbacks();
stateString = tuple[ 5 ];
// promise.progress = list.add
// promise.done = list.add
// promise.fail = list.add
promise[ tuple[ 1 ] ] = list.add;//
//页面元素的监听,(这是主要方法)
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 );
} else {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed );
// A fallback to window.onload, that will always work
window.addEventListener( "load", completed );
}
}
return readyList.promise( obj );
};
// Kick off the DOM ready check even if the user does not
jQuery.ready.promise();//这个方法在页面初始化的时候就执行了
进入jQuery.callbacks=function(){self={add:function(){}}}
self = {
// Add a callback or a collection of callbacks to the list
add: function() {
if ( list ) {
// If we have memory from a past run, we should fire after adding
if ( memory && !firing ) {
firingIndex = list.length - 1;
queue.push( memory );
}
( function add( args ) {
jQuery.each( args, function( _, arg ) {
if ( jQuery.isFunction( arg ) ) {
if ( !options.unique || !self.has( arg ) ) {
list.push( arg );
}
} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
// Inspect recursively
add( arg );
}
} );
} )( arguments );
if ( memory && !firing ) {
fire();
}
}
return this;
}
进入html页面执行$(document).ready(function(){})后面的代码
进入下面的函数;
function completed() {
document.removeEventListener( "DOMContentLoaded", completed );
window.removeEventListener( "load", completed );
jQuery.ready();
}
然后进入ready();这个函数
// Handle when the DOM is ready
ready: function( wait ) {
// Abort if there are pending holds or we're already ready
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;
}
// Remember that the DOM is ready
jQuery.isReady = true;
// If a normal DOM Ready event fired, decrement, and wait if need be
if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
// If there are functions bound, to execute
readyList.resolveWith( document, [ jQuery ] );//deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
}
进入下面的函数
// Call all callbacks with the given context and arguments
fireWith: function( context, args ) {
if ( !locked ) {
args = args || [];
args = [ context, args.slice ? args.slice() : args ];
queue.push( args );
if ( !firing ) {
fire();
}
}
return this;
进入jQuery.callbacks=function(){fire=function(){}}
// Fire callbacks
fire = function() {
// Enforce single-firing
locked = options.once;
// Execute callbacks for all pending executions,
// respecting firingIndex overrides and runtime changes
fired = firing = true;
for ( ; queue.length; firingIndex = -1 ) {
memory = queue.shift();
while ( ++firingIndex < list.length ) {
// Run callback and check for early termination
if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
options.stopOnFalse ) {
// Jump to end and forget the data so .add doesn't re-fire
firingIndex = list.length;
memory = false;
}
}
}
// Forget the data if we're done with it
if ( !options.memory ) {
memory = false;
}
firing = false;
// Clean up if we're done firing for good
if ( locked ) {
// Keep an empty list if we have data for future add calls
if ( memory ) {
list = [];
// Otherwise, this object is spent
} else {
list = "";
}
}
}
上面就执行完 completed函数;
window.addEventListener( "load", function(){
console.log("come in load")
} );
document.addEventListener("DOMContentLoaded",function(){
console.log("come in interactive");})
$(document).ready(function(){
console.log(document.readyState)//interactive--完全加载(completed)前面一个状态可以和页面的DOM元素交互;
})
console.log(1);
/**结果**/
1
interactive(疑问同样是对“DOMContentLoaded”的监听为什么jQuery还是快)
come in interactive
come in load