onload的弔詭

onload是W3C DOM 中定義的事件,該事件會在圖片或文件載入完成時送出..何謂載入完成??

所謂的載入完成包含了文件本身,和其他附屬的資源,

例如是圖像,樣式表,或是script。

可以使用onload事件的HTML標籤有下面幾種:

<body>, <frame>, <frameset>, <iframe>, <img>, <link>, <script>

語法:

onload="JavaScript Code"

其中,雙引號中的字串會被當成程式碼來執行。

所以我們可以在字串中呼叫函式來處理onload事件,

也可以直接把程式碼寫入,譬如下面兩種用法:

<body onload="functiona()"></body>

<body onload="var a=5;var b=6;alert(a+b);"></body>

若是想要在文件載入完成後呼叫兩個程式,可以直接這樣使用:

<body onload="functiona();functionb();"></body>

在文件載入完成時,functiona跟functionb都會被執行到。

除了在<body>標籤使用onload屬性外,

也可以在javascript程式碼當中使用window.onload,像是這樣:

window.onload = function (){ some javascript codes}

或是

window.onload=funA;

這兩種做法與<body onload="funA()"></body>是相同的。

但是這裡有些陷阱要注意,看看下面這種寫法,這是錯誤的:

錯誤:window.onload="var a=5;var b=6;alert(a+b);";

window.onload預期收到的是個函式,而不是字串,即便是由javascript code組成的字串。

下面這也是錯誤的,其實無法藉由這種方式來呼叫兩個onload處理函式:

錯誤:window.onload="funA();funB();" ;

另外還有一個陷阱,很容易忽略:window.onload具有覆寫性。

window.onload=funA; 

window.onload=funB;

這兩行最後只有funB()會被執行。

所以如果說要用window.onload觸發2個以上函式的話。

可以使用下面的方法:

window.onload=function(){

funA();

funB();

}

當然也可能會有些特殊的狀況,譬如說文檔同時引用多個外部javascript檔,

如果有其他js檔有呼叫window.onload,自己在編寫的時候又呼叫了一次window.onload

就可能會造成的window.onload互相覆蓋掉,造成無法預期的結果!

要解決這問題 我們可以嘗試這樣寫:

var oldonload = window.onload || function () {};

window.onload = function () {

oldonload();

// javascript code

}

先將原本的window.onload程式指定給其他變數,保留下來,

然後再重新指定window.onload並在其中函式呼叫原來的onload事件,以確保兩個函式都會被執行到。

另外,除了window物件外還有一些物件支援onload事件:

image, layer, window

上面所提到的都是javascript內建的方式,

其實我們常用的函式庫jQuery中也有個.onload可以用,

功能與window.onload完全相同。

jQuery的.onload使用起來會像是這樣:

$(window).load(function () {
// run code
});

jQuery中還有一個.ready也有類似的功能,.ready會監聽DOMContentLoaded事件,

所以它不需要等外部資源下載完畢就可以開始執行,而且他不會互相覆蓋。

.ready的用法:

  • $(document).ready(handler)
  • $().ready(handler) =>官方網站不建議使用這個。
  • $(handler)

jquery 官方網站上有提到jquery與<body onload=""> 乎相衝突和用的的話會產生問題,最好是不要混用。

至於 <body onload=""> 與 window.onload 會不會衝突?? 其實會...兩個其實會互相覆蓋的..

不過如果寫code時出了點語法錯誤 譬如說window.onload=funA 寫成 window.onload=funA()...

那就會導致瀏覽器執行到這行時 先執行的funA()函式 然後再把傳回值指定給window.onload..

有時候這樣的執行結果 看起來就有點像是 winndow.onload 與 <body onload=""> 都執行成功了...

通常看起來的結果會有點像是先執行了winndow.onload 在執行<body onload=""> 的指定函式..

不過如果你有開除錯模式會發現 window.onload=funA() 這行會有錯誤,因為window.onload期望收到的值是個函式(除非funA() 還真傳回了一個函式..)

還有一個誤區 在執行funA()的時候,HTML檔很可能都沒讀完 如果企圖在這時對文件做操作,那就好笑了..

MDN中的window.onload:window.onload()

 
 

  按個讚!~支持本站!~

FB推薦載入中  

你可能會有興趣的文章