js便簽筆記——jQuery中的ready()事件為何需要那麼多代碼?

來源:互聯網
上載者:User

前言:ready()事件的應用,是大家再熟悉不過的了,學jQuery的第一步,最最常見的代碼: jQuery(document).ready(function () { });jQuery(function () { });$(document).ready(function () { });$(function () { });以上四行代碼的目的和效果都一樣——待DOM載入完成之後,執行傳入的function函數。 再對jquery稍微熟悉一點的朋友可能知道,這裡的“待DOM載入完成”,不是window.onload事件,window.onload是指“DOM載入完成 + DOM相關的檔案下載完成”。這裡的“DOM載入完成”,不包括“DOM相關的檔案載入完成”。相關的事件是: DOMContentLoaded事件(IE9+以及其他瀏覽器)onreadystatechange事件(IE9以下瀏覽器)問題就在這裡。如果知道了這兩個事件,那麼把傳入的function函數關聯到這兩個事件上就行了,而jquery中與ready相關的代碼洋洋洒洒的寫了那麼多,至於上百行代碼。這是為何? 原因在於以下幾點:   2. 儲存結構——基於非同步隊列設計:先看以下代碼: 複製代碼        //應用ready事件        $(function () {            alert(10);        });        $(function () {            alert(20);        });        $(function () {            alert(30);        });複製代碼以上代碼連續應用了三次ready方法,其實jquery是用本身的jquery.callbacks來處理的。主要代碼如下: readyList = jQuery.Callbacks( "once memory" );readyList.add( fn );readyList.fireWith( document, [ jQuery ] );"once":代表add進來的函數只被調用一次; "memory":代表一旦readylist被執行過一次,那麼它後續添加進來的函數會立即按照執行時候的環境和參數執行。   3. 巧妙的事件綁定:以IE9+和其他瀏覽器支援的DOMContentLoaded為例。先看代碼: 複製代碼        // Mozilla, Opera and webkit nightlies currently support this event        if ( document.addEventListener ) {            // Use the handy event callback            document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );             // A fallback to window.onload, that will always work            window.addEventListener( "load", jQuery.ready, false );        }        DOMContentLoaded = function() {        document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );        jQuery.ready();    };複製代碼根據以上代碼可見,最終DOMContented事件執行的,其實是jQUery.ready()這個工具函數。(注意,jquery.ready()和jquery(document).raedy()不一樣!!,前者是工具函數,後者是執行個體函數。) 這裡是通過定義一個DOMContentLoaded函數作為橋樑來執行jquery.ready()函數的,這樣做的目的就是為了即使的remove掉document的DOMContentLoaded事件的引用。 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );單獨把這兩行摘出來,可以看明白,add完了之後,接著remove掉了,在這中間,巧妙的執行了jquery.ready(),這種用法值得學習! 反過來,如果像以下代碼那麼樣實現,document的DOMContentLoaded事件的引用將無法及時刪除。 //反例document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );    另外,除了通過瀏覽器的DOMContentLoaded/onreadystatechange方法可以調用jquery.ready()函數之外,還有一種巧妙的方式調用jquery.ready()函數。 在IE9以下的瀏覽器中,如果當前頁面是頂層(即沒有包含在iframe和friame元素中),調用html.doScroll(),直到不拋出異常,即可調用jquery.ready()函數。 複製代碼 1     if ( document.documentElement.doScroll && toplevel ) { 2                 doScrollCheck(); 3             } 4              5     /*省略*/ 6      7     try { 8         // If IE is used, use the trick by Diego Perini 9         // http://javascript.nwbox.com/IEContentLoaded/10         document.documentElement.doScroll("left");11     } catch(e) {12         setTimeout( doScrollCheck, 1 );13         return;14     }15 16     // and execute any waiting functions17     jQuery.ready();複製代碼  4. 事件執行:上文中講到,可以通過瀏覽器的DOMContentLoaded/onreadystatechange事件,以及對html.doScroll()的檢測來調用jquery.ready()工具函數,jquery.ready()最終將會調用非同步隊列的firewith()方法觸發傳入的所有事件。如果是通過js手動調用,也可以通過jquery事件系統來調用。 readyList.fireWith( document, [ jQuery ] ); if ( jQuery.fn.trigger ) {                jQuery( document ).trigger( "ready" ).off( "ready" );            }  其實這其中還有個jquery.holdready()方法用來延遲調用,不過比較簡單,也不常用,此處不說了。   5. 總結:可見,jQuery中的ready()事件並不是我們看起來那麼簡單,瞭解其原理的同時,也應該想想我們在自己設計系統的時候,考慮的時候全面。 它用到了非同步隊列,使得使用者可以多次調用,順序執行;它的事件綁定考慮到了各種情況,而又充分考慮了資源的釋放;它同時考慮了瀏覽器調用的情況,和js手動調用的情況。個人感受:想瞭解js到底該怎麼用,瞭解js的源碼和設計,是一個捷徑。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.