天天看點

window.onload問題解決啦!

 原文位址: http://dean.edwards.name/weblog/2005/09/busted/ 我所謂的解決隻是針對兩款主要的浏覽器——IE和Mozilla/Firefox。難道這還不夠嗎? 首先,讓我先定義這個問題。程式員在他們的web應用程式的最開始調用window.onload 事件。對于菜單的動态效果或者更複雜的事情,如郵件系統的初始化,使用這個事件是很平常的。但是問題就在于onload事件會在所有頁面内容(包括圖檔和其它二進制内容)被加載後才會觸發。如果你的頁面包含了大量的圖檔,那麼你可能會發現在頁面激活之前有一個顯著的延遲。我們想做的就是尋找一種方法來确定DOM被完全的加載時不用等待所有那些讨厭的圖檔加載完畢。 Mozilla提供了一個特定的事件DOMContentLoaded。下面的代碼準确的實作了在Mozilla平台下,我們想要解決的問題:

window.onload問題解決啦!
//  Mozilla浏覽器
window.onload問題解決啦!
window.onload問題解決啦!
window.onload問題解決啦!
if  (document.addEventListener)  ... {
window.onload問題解決啦!
  document.addEventListener("DOMContentLoaded", init, false);
window.onload問題解決啦!
}

那麼IE怎麼辦呢? IE對

<script>标簽

提供一個非常友善的屬性:defer。這個屬性的意義是訓示IE延遲腳本的加載直到DOM被加載。但是這僅僅對外部腳本起作用。另一個重要的問題是,這個屬性不能使用腳本動态的添加。這意味着,你不能使用DOM方法建立一個腳本并且設定defer屬性,因為這會被忽略。 使用友善的defer屬性,我們能夠建立一個一小段腳本來調用我們的onload事件

window.onload問題解決啦!
< script  defer src ="ie_onload.js"  type ="text/javascript" ></ script >

這個外部腳本的内容僅僅是一行代碼,用來調用我們的onload事件:

init();
  
       

使用這個方法,這就不算問題了。但是其他浏覽器會忽略defer屬性并立即加載腳本。這裡有一些方法來繞過這個問題。我鐘愛的方法是使用 條件注釋對其他浏覽器隐藏這段腳本。

window.onload問題解決啦!
<!-- [if IE]><script defer src="ie_onload.js"></script><![endif] -->

IE也支援 條件編譯。下面的JavaScript代碼和上面的HTML是等效的

window.onload問題解決啦!
//  IE浏覽器
window.onload問題解決啦!
window.onload問題解決啦!
window.onload問題解決啦!
/**/ /*@cc_on @*/
window.onload問題解決啦!
window.onload問題解決啦!
/**/ /*@if (@_win32)
window.onload問題解決啦!
  document.write("<script defer src=ie_onload.js></script>");
window.onload問題解決啦!
/*@end @*/

到目前為止看起來一切順利?我們現在需要支援其他的浏覽器。我們隻有一個選擇——标準的window.onload事件:

window.onload問題解決啦!
//  其他浏覽器
window.onload問題解決啦!
window.onload問題解決啦!
window.onload  =  init;

現在就剩下一個問題了(誰說這個問題簡單?)。因為對于其他浏覽器我們隻能使用onload事件,但是對于IE和Mozilla,我們會調用兩次init方法。為了避開這個問題,我們應當做一個标志方法,以至于onload事件隻執行一次。是以我們的init方法會像下面的代碼一樣:

window.onload問題解決啦!
window.onload問題解決啦!
function  init()  ... {
window.onload問題解決啦!
//如果這個方法已經被調用過,就推出
window.onload問題解決啦!
  if (arguments.callee.done) return;
window.onload問題解決啦!
//标志這個方法以至于我們不會做同樣的事情兩次
window.onload問題解決啦!
  arguments.callee.done = true;
window.onload問題解決啦!
window.onload問題解決啦!
  // 其他操作
window.onload問題解決啦!
} ;
And that, as they say, is that.      

我提供了一個 例子,來證明這個技術。  

繼續閱讀