jQuery ready方法實現
很早之前就留下了這個問題,趕上五一放假,好好研究總結一下吧。
首先jq中ready方法和window的onload方法的不同這裡再提一下,首先ready只是dom樹載入完畢,一些img等資源可能還沒載入完成,而onload則是全部載入成功。而且ready方法可以有多個,而onload只能寫一個。還有一個區別是什麼了,想起來補上。
一般讓我們手寫模擬一個jq的ready方法,我大多都是這樣寫:
document.ready = function (callback) { ///相容FF,Google if (document.addEventListener) { document.addEventListener('DOMContentLoaded', function () { document.removeEventListener('DOMContentLoaded', arguments.callee, false); callback(); }, false) } //相容IE else if (document.attachEvent) { document.attachEvent('onreadystatechange', function () { if (document.readyState == "complete") { document.detachEvent("onreadystatechange", arguments.callee); callback(); } }) } else if (document.lastChild == document.body) { callback(); } }
先檢測DOMContentLoaded事件,然後撤銷繫結,在觸發回撥,IE的就是檢測onreadystatechange事件,如果document.readyState == "complete"就老樣子先撤銷繫結事件,最後觸發回撥,最後就是一個退化操作。
ready方法出現的原因就是window.onload事件是在頁面所有的資源都載入完畢後觸發的. 如果頁面上有大圖片等資源響應緩慢, 會導致window.onload事件遲遲無法觸發.所以出現了DOM Ready事件. 此事件在DOM文件結構準備完畢後觸發, 即在資源載入前觸發.
一般在主流瀏覽器,DOMContentLoaded 事件在許多Webkit瀏覽器以及IE9上都可以使用, 此事件會在DOM文件準備好以後觸發, 包含在HTML5標準中. 對於支援此事件的瀏覽器, 直接使用DOMContentLoaded事件是最簡單最好的選擇.但是IE6,7,8都不支援DOMContentLoaded事件。
在上面程式碼中也就是這樣寫的,第一檢測的還是DOMContentLoaded事件,而且老版本瀏覽器或者IE6-8中,hack的方法就不知一種了:
- 上面也寫到的readyState: 如果瀏覽器存在 document.onreadystatechange 事件,當該事件觸發時,如果 document.readyState=complete 的時候,可視為 DOM 樹已經載入。
eg:
//onreadystatechange event document.onreadystatechange = function(e){ document.getElementById("divMsg").innerHTML += "<br/> onreadystatechange, readyState:" + document.readyState; };
- doScroll檢測:IE瀏覽器文件中說明,當頁面 DOM 未載入完成時,呼叫 doScroll 方法時,會產生異常。(微軟的文件指出doScroll必須在DOM主文件準備完畢時才可以正常觸發)那麼我們反過來用,如果不異常,那麼就是頁面DOM載入完畢了,可以不斷地通過能否執行 doScroll 判斷 DOM 是否載入完畢
//doScroll
var doScrollMoniterId = null;
var doScrollMoniter = function(){
try{
document.documentElement.doScroll("left");
document.getElementById("divMsg").innerHTML += "<br/>doScroll, readyState:" + document.readyState;
if(doScrollMoniterId){
clearInterval(doScrollMoniterId);
}
}
catch(ex){
}
}
doScrollMoniterId = setInterval(doScrollMoniter, 1);
- setTimeout : 在setTimeout中觸發的函式, 一定會在DOM準備完畢後觸發.
var setTimeoutReady = function(){
document.getElementById("divMsg").innerHTML += "<br/> setTimeout , readyState:" + document.readyState;
};
var setTimeoutBindReady = function(){
/in/.test(document.readyState)?setTimeout(arguments.callee, 1):setTimeoutReady();
};
setTimeoutBindReady();
- 外部script: 通過設定了script塊的defer屬性實現.詳見:連結
- 內部script: 外部script的改進版本. 外部script需要頁面引用額外的js檔案. 內部script方法可以避免此問題。詳見:連結
上面的一些方法其實也存在問題,比如readyState狀態為complete的時候圖片已經載入完了。
所以引自一個大佬的說法就是:
具體使用doScroll的話上次看到了這種寫法:
//為了保證最後一定會呼叫ready方法,在上面每一種方式的最後都還是會為load事件繫結ready方法。
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
//這裡的setTimeout是為了非同步
setTimeout( jQuery.ready, 1 );
// Standards-based browsers support DOMContentLoaded
//標準瀏覽器偵聽事件介面:document.addEventListener
} else if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
//文章一開始說了,這裡為了保證一定會觸發ready,所以還針對onload也繫結一次回撥
window.addEventListener( "load", jQuery.ready, false );
// If IE event model is used
} else {
//IE偵聽事件介面:document.attachEvent
//如果有onreadystatechange事件,偵聽之
// Ensure firing before onload, maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );
// http://javascript.nwbox.com/IEContentLoaded/
// 見下邊說明
// If IE and not a frame
// continually check to see if the document is ready
var top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
//如果是IE並且不是iframe
if ( top && top.doScroll ) {
(function doScrollCheck() {
if ( !jQuery.isReady ) {
try {
// Use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
//一直呼叫doScroll滾動,因為DOM渲染結束前,DOM節點是沒有doScroll方法的,所以一直會異常
//直到DOM渲染結束了,這個時候doScroll方法不會丟擲異常,然後就呼叫$.ready()
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
}
// and execute any waiting functions
jQuery.ready();
}
})();
}
}
上面的程式碼即實現這樣的流程:
jQuery原始碼的實現稍有複雜,等日後分析懂了繼續補充。
相關推薦
jQuery ready方法實現
很早之前就留下了這個問題,趕上五一放假,好好研究總結一下吧。 首先jq中ready方法和window的onload方法的不同這裡再提一下,首先ready只是dom樹載入完畢,一些img等資源可能還沒載入完成,而onload則是全部載入成功。而且ready方法可以有多個,而onload只能寫一個。還有一個區別
JS原生方法實現JQuery ready()方法
首先說明一下load事件與ready事件的區別 HTML文件載入順序: ① 解析HTML結構 ② 載入外部指令碼和樣式表文件 ③ 解析並執行指令碼程式碼 ④ 構造HTML DOM模型 ⑤ 載入圖片等外部檔
jquery load()方法實現區域性重新整理,多張網頁切換(li標籤實現上下頁的切換)
---學習借鑑中--- (1)父頁面插入的位置 <div id="content" > //id為要重新整理顯示的子頁面的內容 </div> (2)父頁面顯示標籤切換不同html頁面 <ul class="userMenu"> <li
Jquery load()方法 實現公用頭部 尾部
//這是header.html裡的程式碼,想作為頭部引進來 <div id="loginBox"> <span></span> <div> <div> &l
jQuery load() 方法實現載入遠端資料
jQuery load() 方法是簡單但強大的 AJAX 方法。load() 方法從伺服器載入資料,並把返回的資料放入被選元
跨域問題相關知識詳解(原生js和jquery兩種方法實現jsonp跨域)
syn con 加載 developer 兩種方法 ray exe 編寫 分組 1、同源策略 同源策略(Same origin policy),它是由Netscape提出的一個著名的安全策略。同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽
簡單的實現圖片預覽, 通過原生ajax以及 jQuery兩種方法實現圖片預覽,有更好的辦法可以留言喔................
XML HP OS image end php代碼 append sda ext 1.原生寫ajax實現圖片預覽: 結構: <input type="file"> <img src="" > JavaScri
JQuery擴展方法實現Form表單與Json互相轉換
val adjust new 映射 checked josn fin pop undefined JQuery筆記 記兩段代碼,使用JQuery實現從表單獲取json與後端交互,以及把後端返回的json映射到表單相應的字段上。 把表單轉換出json對象 //把表單
Tab切換欄(jQuery方法實現)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style ty
javascript事件委託理解,jQuery on 方法一步到位實現事件委託
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Jquery的Ready方法載入為什麼兩次?
Ready方法會呼叫兩次? 檢視對應的頁面是否存在<iframe src="#" ……> 存在iframe載入這個頁面的時候,頁面就會載入兩次。 $(document).ready(function(){}和onload的區別? 頁面載入完成有兩種事件: 區別
jQuery中toggle方法實現切換
首先定義myToggle 方法: $.prototype["myToggle"] = function () { var args = arguments; var that = this; var i = 0; var n =
Javascript中onload方法和Jquery中ready方法的區別
1.執行時間 window.onload必須等到頁面內包括圖片的所有元素載入完畢後才能執行。 $(document).ready()是DOM機構繪製完畢後就執行,不必等到載入完畢。 2.編寫個數不同 window.onload不能同時編寫多個,且多個只能執行一個。 $(document).r
jQuery: 使用setInterval()方法實現考試系統的自動提交(ASP.NET)
需求: 要實現考試系統在超過規定的時間後自動提交。 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title
用jQuery的toggle方法實現元素的左右滑動隱藏
通常情況下給元素加toggle方法通常會是上下滑動隱藏,而有時我們又需要左右滑動隱藏怎麼辦呢? JS片段: $(document).ready(function(){ $('#example
jQuery使用JSONP實現跨域獲取資料的三種方法詳解
本文例項講述了jQuery使用JSONP實現跨域獲取資料的三種方法。分享給大家供大家參考,具體如下: 第一種方法是在ajax函式中設定dataType為'jsonp' $.ajax({ dataType: 'jsonp', url: 'http://www.a
37. jQuery- ready()方法的幾種寫法
jquery-ready()方法的四種寫法 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>jQuery- ready()方法的幾種寫法<
52 jQuery-使用fadeIn()和fadeOut()方法實現淡入淡出效果
1.效果圖 2.HTML程式碼 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>52 jQuery-使用fadeIn()和fadeO
51 jQuery-使用slideDown()與slideUp()方法實現滑動效果
1.效果圖 2.HTML程式碼 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>51 jQuery-使用slideDown()與sl
用jquery的ajax方法實現三級聯動
<script>(function(){var p = $('#province');//得到省份的select物件var c = $('#city');//得到城市的select物件var t = $('#town');//得到地區的select物件$.aja