2010年12月30日 星期四

你的網頁已經下載完畢了?

在撰寫 JavaScript 時,我們可能會透過 getElemnetById 或 getElemnetByName 來取得頁面上的物件,或者你想去呼叫某個已經事先定義好的函數。可是,如果網頁上的 DOM 尚未完全載入完畢時,你所執行的 JavaScript 語法,就很有可能會出現錯誤。我參考「Are you ready for this」這篇文章,作者提了一個問題,「你怎麼確定你的網頁已經下載完畢了?」

對於這個問題,首先要清楚網頁對於「下載完畢」的定義有分兩種:第一種:window.onready,是真的所有東西都下載完畢,包括:頁面所參考引用的所有 CSS、Script、Image、Flash。第二種:DOM-ready,則是網頁的DOM階層樹建置完畢,包括頁面上所引用的 CSS、Script。可想而知,第一種 window.onready 是所謂網頁真正完全下載完畢,但是目前的網頁越來越花俏,可能你的頁面有一個非常巨大的圖片連結,而要達到 window.onready 的地步,勢必要花不少時間。比較合適的作法,是第二種 DOM-ready,只需要確保我們執行的 JavaScript 所需的 DOM 階層架構都已經完整,就可以先執行了,不需要去等待圖片或是 flash 的下載。


在我們常見的一個 JavaScript 語法, window.onload=function(){ //Do something. };
他的效果比像上面所提到的第一種 window.onready,所以在我們使用它用的很開心的時候,應該好好想想,這種寫法會不會讓你的程式效能或是給使用者的感觀受影響。「jQuery in Action」一書的作者,在他書裡的第一章節,也提到為了避免讓使用者長時間的等待頁面圖片的下載,建議使用:

$(document).ready(function(){ // Do something. });

因為 jQuery.ready( )的效果,是我們介紹的第二種 DOM-ready 模式 ,可以讓使用者減少等待的時間。不過附帶一提的是, 作者認為使用 window.onload 的另一個缺點,就是他只能使用一次,如果被除重複呼叫或是你程式裡還有其他 third party 函式庫也使用了 window.onload ,就會造成被蓋來蓋去的問題。其實,這部份可以參考「JavaScript 小陷阱 (5) – window.onload()」這篇文章,透過一個小技巧,也是可以讓你重複呼叫多次的 window.onload 。

以下程式碼節錄自JavaScript 小陷阱 (5) – window.onload()

var oldOnload = window.onload || function () {};
window.onload = function ()
{
oldOnload();
// Do Something...
}

透過事先將舊的 onload 事件存放在一個變數,並於自行定義的 onload 事件中,找個適當位置觸發舊的事件。

在上一篇紀錄:「Internet Explorer 無法開啟網際網路網站」,除了使用者自己的瀏覽器問題之外,程式撰寫本身也是有可能會造成這問題。程式的部份,就是 DOM 有沒有完全下載完畢所導致。透過比較清楚的瞭解後,至少下次發生問題時,可以降低因為程式撰寫不良而讓系統出錯的機率。

參考:


01.Are you ready for this
http://www.hunlock.com/blogs/Are_you_ready_for_this
02.JavaScript 小陷阱 (5) – window.onload()
http://www.jaceju.net/blog/archives/160
03.Internet Explorer 無法開啟網際網路網站
http://paladinprogram.blogspot.com/2010/12/internet-explorer.html
04.The window.onload Problem
http://peter.michaux.ca/articles/the-window-onload-problem-still

沒有留言:

張貼留言