JavaScript判斷DOM何時(shí)加載完畢的技巧
更新時(shí)間:2012年11月11日 19:53:39 作者:
處理HTML DOM文檔存在一個(gè)難題是,JavaScript可以在DOM完全加載之前執(zhí)行,這會(huì)給你的代碼引發(fā)不少的潛在問題;針對(duì)這個(gè)問題,本文給予適當(dāng)?shù)慕鉀Q方法,僅供參考
處理HTML DOM文檔存在一個(gè)難題是,JavaScript可以在DOM完全加載之前執(zhí)行,這會(huì)給你的代碼引發(fā)不少的潛在問題。瀏覽器的渲染和操作順序大致如下列表:
HTML解析完畢
外部腳本和樣式表加載完畢
腳本在文檔內(nèi)解析并執(zhí)行
HTML DOM完全構(gòu)造起來
圖片和外部?jī)?nèi)容加載
網(wǎng)頁完成加載
在網(wǎng)頁頭部并且從外部文件加載的腳本會(huì)在HTML真正構(gòu)造之前執(zhí)行。如前所述,這是個(gè)至關(guān)重要的問題,因?yàn)檫@兩處執(zhí)行的腳本并不能訪問還不存在的DOM。幸好,我們還有若干的補(bǔ)救方法。
目前,最常用的級(jí)數(shù)是完全等待整個(gè)頁面加載完畢才執(zhí)行DOM操作。這種技術(shù)只需利用window對(duì)象的load事件來綁定一個(gè)函數(shù),頁面加載完畢即可觸發(fā)。
addEvent(window, "load", function(){
// do something
});
最簡(jiǎn)單的操作卻是最慢的。在加載過程的順序列表中,你會(huì)注意到頁面的加載完畢與否完全被最后一步所掌控。這就是說,如果頁面有很多的圖片、視頻等,用戶可能得登上一段時(shí)間JavaScript才執(zhí)行。
另一種級(jí)數(shù)可用以監(jiān)聽 DOM 加載狀態(tài),可能是最復(fù)雜的(從實(shí)現(xiàn)角度來看),但也是最有效地。
這項(xiàng)技術(shù)在不堵塞瀏覽器加載的情況下盡可能快地檢查 HTML DOM文檔是否已經(jīng)加載了執(zhí)行所必須得屬性。以下是檢查HTML DOM是否可用的幾個(gè)要點(diǎn):
document: 你需要知道DOM文檔是否已經(jīng)加載。若能足夠快地檢查,運(yùn)氣好的話你會(huì)看到undefined。
document.getElementsByTagName和document.getElementById:頻繁使用document.getElementsByTagName和document.getElementById函數(shù)檢查文檔,當(dāng)存在這些函數(shù)則表明DOM已經(jīng)加載完畢。
document.body: 作為額外補(bǔ)充,檢查元素是否已經(jīng)完全加載。理論上前一個(gè)檢查應(yīng)該已經(jīng)能做出判斷,但我發(fā)現(xiàn)有些情況下還是不夠。
使用這些檢查就足夠判斷DOM是否可用了(“足夠”在此表示可能會(huì)有一定毫秒級(jí)的時(shí)間差)。這個(gè)方法幾乎沒有瑕疵。單獨(dú)使用前述檢查,腳本應(yīng)該可以在現(xiàn)代瀏覽器中運(yùn)行得相對(duì)良好。但是,最近(2008年?)Firefox實(shí)現(xiàn)了緩存改進(jìn),使得window加載事件實(shí)際上可以在腳本能檢查到DOM是否可用之前觸發(fā)。為了能發(fā)揮這個(gè)優(yōu)勢(shì),我同時(shí)為window加載事件附加檢查,以期能獲得更快的執(zhí)行速度。
最后,domReady函數(shù)集合了所有需要在DOM可用時(shí)就執(zhí)行的函數(shù)的引用。一旦DOM被認(rèn)為是可用的,就調(diào)用這些引用并按順序一一執(zhí)行。
// 監(jiān)聽 DOM 是否可用的函數(shù)
function domReady(f) {
// 假如DOM已經(jīng)加載,馬山執(zhí)行函數(shù)
if(domReady.done) return f();
// 假如我們已經(jīng)增加了一個(gè)函數(shù)
if(domReady.timer) {
// 把它假如待執(zhí)行函數(shù)清單中
domReady.ready.push(f);
} else {
// 為頁面加載完畢綁定一個(gè)事件,以防它最先完成。
addEvent(window, "load", isDOMReady);
// 初始化執(zhí)行函數(shù)的數(shù)組
domReady.ready = [f];
// 盡可能快的檢查DOM是否已可用
domReady.timer = setInterval(isDOMReady, 13);
}
}
// 檢查 DOM 是否已可操作
function isDOMReady() {
// 如果我們能判斷出DOM已可能,忽略
if(domReady.done) return false;
// 檢查若干函數(shù)和元素是否可能
if(document && document.getElementsByTagName && document.getElementById && document.body) {
// 如果可用,我們停止檢查
clearInterval(domReady.timer);
domReady.timer = null;
// 執(zhí)行所有正在等待的函數(shù)
for(var i = 0; i < domReady.ready.length; i++) {
domReady.ready[i]();
// 記錄我們?cè)诖艘呀?jīng)完成
domReady.ready = null;
domReady.done = true;
}
}
}
現(xiàn)在我們來看看在HTML文檔中是如何執(zhí)行的。假設(shè)已經(jīng)將domReady函數(shù)寫到一個(gè)名為domready.js的外部文件中
<html>
<head>
<title> Testing DOM Loading</title>
<script src="domready.js"></script>
<script>
domReady(function(){
alert("The DOM is loaded!");
// do something
});
</script>
</head>
<body>
<h1>Testing DOM Loading</h1>
<!-- 這里是大量的HTML -->
</body>
</html>
HTML解析完畢
外部腳本和樣式表加載完畢
腳本在文檔內(nèi)解析并執(zhí)行
HTML DOM完全構(gòu)造起來
圖片和外部?jī)?nèi)容加載
網(wǎng)頁完成加載
在網(wǎng)頁頭部并且從外部文件加載的腳本會(huì)在HTML真正構(gòu)造之前執(zhí)行。如前所述,這是個(gè)至關(guān)重要的問題,因?yàn)檫@兩處執(zhí)行的腳本并不能訪問還不存在的DOM。幸好,我們還有若干的補(bǔ)救方法。
目前,最常用的級(jí)數(shù)是完全等待整個(gè)頁面加載完畢才執(zhí)行DOM操作。這種技術(shù)只需利用window對(duì)象的load事件來綁定一個(gè)函數(shù),頁面加載完畢即可觸發(fā)。
復(fù)制代碼 代碼如下:
addEvent(window, "load", function(){
// do something
});
最簡(jiǎn)單的操作卻是最慢的。在加載過程的順序列表中,你會(huì)注意到頁面的加載完畢與否完全被最后一步所掌控。這就是說,如果頁面有很多的圖片、視頻等,用戶可能得登上一段時(shí)間JavaScript才執(zhí)行。
另一種級(jí)數(shù)可用以監(jiān)聽 DOM 加載狀態(tài),可能是最復(fù)雜的(從實(shí)現(xiàn)角度來看),但也是最有效地。
這項(xiàng)技術(shù)在不堵塞瀏覽器加載的情況下盡可能快地檢查 HTML DOM文檔是否已經(jīng)加載了執(zhí)行所必須得屬性。以下是檢查HTML DOM是否可用的幾個(gè)要點(diǎn):
document: 你需要知道DOM文檔是否已經(jīng)加載。若能足夠快地檢查,運(yùn)氣好的話你會(huì)看到undefined。
document.getElementsByTagName和document.getElementById:頻繁使用document.getElementsByTagName和document.getElementById函數(shù)檢查文檔,當(dāng)存在這些函數(shù)則表明DOM已經(jīng)加載完畢。
document.body: 作為額外補(bǔ)充,檢查元素是否已經(jīng)完全加載。理論上前一個(gè)檢查應(yīng)該已經(jīng)能做出判斷,但我發(fā)現(xiàn)有些情況下還是不夠。
使用這些檢查就足夠判斷DOM是否可用了(“足夠”在此表示可能會(huì)有一定毫秒級(jí)的時(shí)間差)。這個(gè)方法幾乎沒有瑕疵。單獨(dú)使用前述檢查,腳本應(yīng)該可以在現(xiàn)代瀏覽器中運(yùn)行得相對(duì)良好。但是,最近(2008年?)Firefox實(shí)現(xiàn)了緩存改進(jìn),使得window加載事件實(shí)際上可以在腳本能檢查到DOM是否可用之前觸發(fā)。為了能發(fā)揮這個(gè)優(yōu)勢(shì),我同時(shí)為window加載事件附加檢查,以期能獲得更快的執(zhí)行速度。
最后,domReady函數(shù)集合了所有需要在DOM可用時(shí)就執(zhí)行的函數(shù)的引用。一旦DOM被認(rèn)為是可用的,就調(diào)用這些引用并按順序一一執(zhí)行。
復(fù)制代碼 代碼如下:
// 監(jiān)聽 DOM 是否可用的函數(shù)
function domReady(f) {
// 假如DOM已經(jīng)加載,馬山執(zhí)行函數(shù)
if(domReady.done) return f();
// 假如我們已經(jīng)增加了一個(gè)函數(shù)
if(domReady.timer) {
// 把它假如待執(zhí)行函數(shù)清單中
domReady.ready.push(f);
} else {
// 為頁面加載完畢綁定一個(gè)事件,以防它最先完成。
addEvent(window, "load", isDOMReady);
// 初始化執(zhí)行函數(shù)的數(shù)組
domReady.ready = [f];
// 盡可能快的檢查DOM是否已可用
domReady.timer = setInterval(isDOMReady, 13);
}
}
// 檢查 DOM 是否已可操作
function isDOMReady() {
// 如果我們能判斷出DOM已可能,忽略
if(domReady.done) return false;
// 檢查若干函數(shù)和元素是否可能
if(document && document.getElementsByTagName && document.getElementById && document.body) {
// 如果可用,我們停止檢查
clearInterval(domReady.timer);
domReady.timer = null;
// 執(zhí)行所有正在等待的函數(shù)
for(var i = 0; i < domReady.ready.length; i++) {
domReady.ready[i]();
// 記錄我們?cè)诖艘呀?jīng)完成
domReady.ready = null;
domReady.done = true;
}
}
}
現(xiàn)在我們來看看在HTML文檔中是如何執(zhí)行的。假設(shè)已經(jīng)將domReady函數(shù)寫到一個(gè)名為domready.js的外部文件中
復(fù)制代碼 代碼如下:
<html>
<head>
<title> Testing DOM Loading</title>
<script src="domready.js"></script>
<script>
domReady(function(){
alert("The DOM is loaded!");
// do something
});
</script>
</head>
<body>
<h1>Testing DOM Loading</h1>
<!-- 這里是大量的HTML -->
</body>
</html>
相關(guān)文章
JavaScript實(shí)現(xiàn)QQ聊天室功能
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)QQ聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
微信小程序開發(fā)之實(shí)現(xiàn)食堂點(diǎn)餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了如何通過微信小程序開發(fā)一個(gè)簡(jiǎn)單的食堂點(diǎn)餐系統(tǒng),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以和小編一起學(xué)習(xí)一下2023-01-01
原生js結(jié)合html5制作小飛龍的簡(jiǎn)易跳球
這篇文章主要介紹了原生js結(jié)合html5制作小飛龍的簡(jiǎn)易跳球的方法和代碼分享,推薦給大家,有需要的小伙伴可以參考下。2015-03-03
ECharts柱狀圖過多添加滾動(dòng)條的步驟(親測(cè)可用)
這篇文章主要介紹了ECharts柱狀圖過多添加滾動(dòng)條的步驟(親測(cè)可用),添加echarts柱狀圖滾動(dòng)條,首先添加js用來判斷當(dāng)前視圖要顯示幾個(gè)及是否顯示滾動(dòng)條,本文結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友參考下吧2024-01-01
javascript使用alert實(shí)現(xiàn)一個(gè)精美的彈窗
其實(shí)最初使用alert還是一個(gè)常態(tài),包括現(xiàn)在很多B端平臺(tái)還在直接使用alert,本文主要介紹了javascript使用alert實(shí)現(xiàn)一個(gè)精美的彈窗,感興趣的可以了解一下2023-02-02
js實(shí)現(xiàn)的訂閱發(fā)布者模式簡(jiǎn)單示例
這篇文章主要介紹了js實(shí)現(xiàn)的訂閱發(fā)布者模式,結(jié)合完整示例形式分析了js訂閱發(fā)布者模式相關(guān)實(shí)現(xiàn)與使用方法,需要的朋友可以參考下2020-03-03

