做web開發時常用query中$(document).ready()和JavaScript中的Bwindo.onload方法,兩者都是要在頁面加載完成以後加載的方法,但是這兩者還是有很大區別的。最近遇到了這樣的問題,查詢了多篇文章,做一下總結。
簡單來說,要以用以下張表來表示 :
window.onload() | $(document).ready() | |
加載時機 | 必須等待網頁全部加載完畢(包括圖片等),然後再執行JS代碼 | 只需要等待網頁中的DOM結構加載完畢,就能執行JS代碼 |
執行次數 | 只能執行一次,如果第二次,那麼第一次的執行會被覆蓋 | 可以執行多次,第N次都不會被上一次覆蓋 |
舉例 | 以下代碼無法正確執行: window.onload = function() { alert(“text1”);};
window.onload = function() { alert(“text2”);}; 結果只輸出第二個 | 以下代碼正確執行: $(document).ready(function(){alert(“Hello”)}); 結果兩次都輸出 |
簡寫方案 | 無 | $(function () {}) |
一般情況下window的load()都是用來設置body標籤的onload事件.但onload事件是要在頁面的元素全部加載完了才觸發的,這也包括頁面上的圖片,以及大的表格數據。如果頁面上圖片較多或圖片太大,加載需要較多時間,就會導致頁面無響應,或者用戶做了其它操作了。
而Jeuery中的ready()則是在頁面的dom(節點)加載完後就可以做相應的操作,而不用等待全部元素加載完成.比如只知道頁面某處有一張圖片,而不一定要等它顯示出來就可以爲它綁定點擊方法。
load()一般不建議使用,這裏主要講一下( $(selector).ready())。
原理:
在jquery腳本加載的時候,會設置一個isReady的標記,監聽DOMContentLoaded事件(這個不是什麼瀏覽器都有的,不同瀏覽器,jquery運作方式不一樣).當然遇到調用ready函數的時候,如果isReady未被設置,那就是說頁面未加載完,就會把要執行的函數用一個數組緩存起來,當頁面加載完後,再把緩存的函數一一執行.
Jquery中的詳細代碼分析:
ready: function(fn) { // 綁定監聽器 bindReady(); // 如果 DOM 加載完成 if ( jQuery.isReady ) // 馬上運行此函數 fn.call( document, jQuery ); // 否則保存起來 else // 把函數加入緩存數組中 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); return this; }
當然,jquery對不同的瀏覽器dom加載完成的通知 bindReady()函數也是不同的
var readyBound = false; function bindReady(){ if ( readyBound ) return; readyBound = true; // Mozilla,opera,webkitnightlies支持DOMContentLoaded事件 if ( document.addEventListener && !jQuery.browser.opera) // 直接使用事件回調即可 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); // 如果是ie並且不是嵌在frame中 // 就需要不斷地檢查文檔是否加載完 if ( jQuery.browser.msie && window == top ) (function(){ if (jQuery.isReady) return; try { document.documentElement.doScroll("left"); } catch( error ) { 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++) 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" ) { setTimeout( arguments.callee, 0 ); return; } if ( numStyles === undefined ) numStyles = jQuery("style, link[rel=stylesheet]").length; if ( document.styleSheets.length != numStyles ) { 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 ); } }
這裏最要注意的是,IE只有在頁面不是嵌入frame中的情況下才和其它瀏覽器等一樣,在DOM加載完成以後就執行$(document).ready()的內容。
參考文章:1、http://www.cnblogs.com/kingwell/archive/2012/09/09/2677252.html
2、http://blog.csdn.net/xiebaochun/article/details/36375481