jQuery(事件-頁面事件ready(fn)) 3.0

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
發佈了80 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章