jquery ready 原理

轉  http://www.cnblogs.com/fullhouse/archive/2012/03/07/2384016.html


jQuery是一套跨瀏覽器的JavaScript函式庫,強化HTML與JavaScript之間的操作。由John Resig在2006年1月的BarCamp NYC上釋出第一個版本。目前全球有28%的站臺使用jQuery,是目前最受歡迎的JavaScript函式庫。

jquery ready函數源代碼:一般情況下都是設置body標籤的onload監聽window的load事件.但load事件是要在頁面的元素全部加載完了才觸發的,如果頁面上圖片較多或圖片太大,就會導致初始化的代碼未被執行的時候用戶就做了其它操作了. Jquery庫提供了一個非常方便好用的函數( $(selector).ready()),讓我們可以在頁面的dom加載完後就可以做相應的操作(當然,這還得看用戶瀏覽器的支持).,而不用等待全部元素加載完成.例如: 
$(document).ready(function (){ alert('use in page script tag') }); 
$(document).ready(function (){ alert('use in import js file') }); 
現在讓我們來研究一下這個函數的實現. 
原理: 
在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 { 
// 這個地方標記一下,在後面解析(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未完成解析時,調用document的document.documentElement.doScroll(”left”)會出錯這個小技巧便可得知dom有沒有ready了. 
(2):setTimeout( arguments.callee, 0 )這句是表示延遲0秒調用,實際上它不會馬上就調用,而是會盡可能快地調用,它告訴瀏覽器爲當前任何掛起的事件運行完事件句柄並且完成了文檔當前狀態的更新後才調用. Arguments.callee即是外層的匿名函數,參數的調用者 
(3):這個地方你也許覺得奇怪,爲什麼不在mozilla那裏一起處理呢? 原因就是opera的DOMContentLoaded事件發生後,其css樣式是還沒完全可用的,所以要特殊處理,就是判斷每個css的tag都是不是enable了. 
(4),(5):safari中document.readyState的狀態爲loaded或complete時,css文件引入還未能確定是不是解析完了的,所以要通過判斷其css文件數目 
(6):最後,如果上面的hack都不支持的話…就用最保險的load事件,保證能執行到初始化代碼.



轉 http://www.jb51.net/article/23927.htm

jquery ready()的幾種實現方法小結

1.最常用也是最標準的 

$(document).ready(){ 
}); 


2.是上面的簡寫: 

$(function(){ 
}) 

很奇怪?爲什麼能這樣?不是判斷document對象是否 reADy然後才執行函數的麼?document哪去了?我們看下jQuery的源代碼: 

// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}



找到了,我們再看下$這個方法的參數 
$(selector,context) 
第一個爲選擇器,第二個是容器 
如果不填就默認爲document 
3.好吧!我承認這個方式是來打醬油的 

複製代碼代碼如下:
jQuery(document).ready(function(){ 
}); 

4. 
複製代碼代碼如下:
jQuery(function($){ 
alert($("#ready1").html()); 
}); 

第四種方式和第三種沒有區別啊?各位客官仔細看!我們給functIOn傳了一個參數$ 
第四種方式一般用在處理jQuery的$和別的庫衝突的時候用的,通過jQuery.noConflict()這個方法,我們就可以直接在代碼中通過jQuery來代替$來使用,但又習慣了使用$怎麼辦?看下面的代碼: 
複製代碼代碼如下:
jQuery.noConflict(); 
jQuery(function($){ 
alert($("#ready1").html()); //我們又能用上$符號了 
}); 

上面是目前本人知道的幾種jQuery的ready ()的寫法.如果還有其他的寫法,望告知


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章