欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jquery ready函數(shù)源代碼研究

 更新時間:2009年12月06日 00:57:12   作者:  
我們都知道,很多時候,在頁面加載完后都需要做一些相應的初始化動作.例如,運行某些js特效,設置表單等等.怎么知道頁面加載完了呢?
一般情況下都是設置body標簽的onload監(jiān)聽window的load事件.但load事件是要在頁面的元素全部加載完了才觸發(fā)的,如果頁面上圖片較多或圖片太大,就會導致初始化的代碼未被執(zhí)行的時候用戶就做了其它操作了. Jquery庫提供了一個非常方便好用的函數(shù)( $(selector).ready()),讓我們可以在頁面的dom加載完后就可以做相應的操作(當然,這還得看用戶瀏覽器的支持).,而不用等待全部元素加載完成.例如:
$(document).ready(function (){ alert('use in page script tag') });
$(document).ready(function (){ alert('use in import js file') });
現(xiàn)在讓我們來研究一下這個函數(shù)的實現(xiàn).
原理:
在jquery腳本加載的時候,會設置一個isReady的標記,監(jiān)聽DOMContentLoaded事件(這個不是什么瀏覽器都有的,不同瀏覽器,jquery運作方式不一樣).當然遇到調(diào)用ready函數(shù)的時候,如果isReady未被設置,那就是說頁面未加載完,就會把要執(zhí)行的函數(shù)用一個數(shù)組緩存起來,當頁面加載完后,再把緩存的函數(shù)一一執(zhí)行.
Jquery中的詳細代碼分析:


復制代碼 代碼如下:

ready: function(fn) {
        // 綁定監(jiān)聽器
        bindReady();
        // 如果 DOM 加載完成
        if ( jQuery.isReady )
            // 馬上運行此函數(shù)
            fn.call( document, jQuery );
        // 否則保存起來
        else
            // 把函數(shù)加入緩存數(shù)組中
            jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
        return this;
}


讓我們看看jquery如果實現(xiàn)不同瀏覽器dom加載完成的通知 bindReady()函數(shù):

復制代碼 代碼如下:

var readyBound = false;
function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

// Mozilla,opera,webkitnightlies支持DOMContentLoaded事件
    if ( document.addEventListener && !jQuery.browser.opera)
        // 直接使用事件回調(diào)即可
        document.addEventListener( "DOMContentLoaded", jQuery.ready, false );

    // 如果是ie并且不是嵌在frame中
    // 就需要不斷地檢查文檔是否加載完
    if ( jQuery.browser.msie && window == top ) (function(){
        if (jQuery.isReady) return;
        try {
            // 這個地方標記一下,在后面解析(1)
            document.documentElement.doScroll("left");
        } catch( error ) {
//// 這個地方標記一下,在后面解析(2)
            setTimeout( arguments.callee, 0 );
            return;
        }
        // and execute any waiting functions
        jQuery.ready();
    })();

    if ( jQuery.browser.opera )
        document.addEventListener( "DOMContentLoaded", function () {
            if (jQuery.isReady) return;
            for (var i = 0; i < document.styleSheets.length; i++) // 標記(3)
                if (document.styleSheets[i].disabled) {
                    setTimeout( arguments.callee, 0 );
                    return;
                }
            // and execute any waiting functions
            jQuery.ready();
        }, false);

    if ( jQuery.browser.safari ) {
        var numStyles;
        (function(){
            if (jQuery.isReady) return;
            if ( document.readyState != "loaded" && document.readyState != "complete" ) { // 標記(4)
                setTimeout( arguments.callee, 0 );
                return;
            }
            if ( numStyles === undefined )
                numStyles = jQuery("style, link[rel=stylesheet]").length;
            if ( document.styleSheets.length != numStyles ) { // 標記(5)
                setTimeout( arguments.callee, 0 );
                return;
            }
            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready ); // 標記(6)
}
}


(1):這個主要是測出ie下的dom ready,原理在這里http://javascript.nwbox.com/IEContentLoaded/,利用在ie下.當dom未完成解析時,調(diào)用document的document.documentElement.doScroll(”left”)會出錯這個小技巧便可得知dom有沒有ready了.
(2):setTimeout( arguments.callee, 0 )這句是表示延遲0秒調(diào)用,實際上它不會馬上就調(diào)用,而是會盡可能快地調(diào)用,它告訴瀏覽器為當前任何掛起的事件運行完事件句柄并且完成了文檔當前狀態(tài)的更新后才調(diào)用. Arguments.callee即是外層的匿名函數(shù),參數(shù)的調(diào)用者
(3):這個地方你也許覺得奇怪,為什么不在mozilla那里一起處理呢? 原因就是opera的DOMContentLoaded事件發(fā)生后,其css樣式是還沒完全可用的,所以要特殊處理,就是判斷每個css的tag都是不是enable了.
(4),(5):safari中document.readyState的狀態(tài)為loaded或complete時,css文件引入還未能確定是不是解析完了的,所以要通過判斷其css文件數(shù)目
(6):最后,如果上面的hack都不支持的話…就用最保險的load事件,保證能執(zhí)行到初始化代碼.

相關文章

最新評論