2007年03月5日

JavaScript 小陷阱 (5) - window.onload()

我常會在頁面載入完成時,利用 window.load 來執行一些動作。基本的方式如下:


window.onload = function ()
{
  // Do something...
}

特別注意一點:如果直接把新動作附在 window.onload 的話,是會把前一個 window.onload 的動作給蓋掉的。

不過如果現在有兩個動作都需要用到 window.onload ,而且其中一個我不想改動時該怎麼辦呢? (例如是第三方函式庫裡的程式)


這時可以改用以下的方式:

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

換句話說,就是先把舊的 window.onload 放在一個變數裡,然後在新的 window.onload 裡呼叫它。

很重要的一點是,一定要加上「 || function () {} 」!這樣做的目的,是怕如果在此之前沒有指定 window.onload (也就是 undefined) 時,瀏覽器會出現 JavaScript 錯誤。

依照同樣的方式,我們可以讓多個 window.onload 動作:

var beforeAction1 = window.onload || function () {};
window.onload = function () // Functin A
{
  beforeAction1();
  alert('Action 1');
}

var afterAction2 = window.onload || function () {};
window.onload = function () // Functin B
{
  alert('Action 2');
  afterAction2();
}

注意 after 及 before 的命名方式,如果我希望舊的 window.onload 在我目前的動作之前執行,用 before 會比較好;反之就可以用 after 。


Posted by jaceju at 樂多Roodo! │18:16 │回應(11)引用(0)JavaScript
樂多分類:網路/3C 共同主題:Java/JavaScript 工具:加入樂多書籤編輯本文
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/2808099
回應文章
請問一下,蓋掉先前的連結,會造成什麼樣的影響?
Posted by 陳富霖 at 2007年08月14日 12:20
舊的 window.onload 就沒辦法執行了,如此而已。
Posted by jaceju at 2007年08月14日 12:50
請問把要自動執行的javascript敘述直接寫在</body>前或後的區塊裡(不寫成function)

寫成function用<body onload="xxx()">呼叫
這兩種方式有什麼差異?
(假設沒有像您動態增加自動執行動作的需求)
Posted by Simon at 2007年11月14日 18:24
(html碼跑掉了)
我是指放在</body>前或後的<script>區塊裡
Posted by Simon at 2007年11月14日 18:28

To Simon:

1. script 可以放在 head 或 body 標籤內,但不可以放在這兩個標籤外;因為這樣是不合 HTML 規範的,會使得有些瀏覽器會沒辦法讀取。所以 script 不能放在 </body> 後面。

2. 如果沒用 function 的 script 放在 </body> 前面,其實和 onload 的方式差不多;只不過這時因為 body 還沒被載入 DOM ,所以可能會有一些奇怪的 Bug 發生。

所以還是建議你用 onload 的方式會比較好,或是利用其他 JavaScript Library 的 ready 方法來處理,會讓你的程式比較穩定一些。
Posted by jaceju at 2007年11月14日 18:44

邏輯上想不通...
譬如:
<html>
<head>
<script>
function doThisOnLoad() {
  //something...
}

var oldOnload = window.onload || function () {};
window.onload = function ()
{
  oldOnload();
  // Do Something...
}
</script>
</head>
<body onload="doThisOnLoad();"></body>
</html>
上面的<script>區塊究竟是在<body>前還是後執行的呢?
如果是在前
那oldOnload取到的值應該是function(){}而不是doThisOnLoad()
因為當時還沒執行到<body>不是嗎?
還是說browser在處理完body後才會執行<header>裡的<script>區塊裡沒有包成function的敘述?
Posted by Simon at 2007年11月15日 11:29

To Simon:

1. onload 事件會在整個 HTML 頁面 (包含圖片等) 載完後才執行。

2. body 的 onload 會蓋掉你上面的 window.onload 的指定,也就是類似以下的程式碼:

function doThisOnLoad() {
//something...
}

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

// 在 body onload 等同於這樣:
window.onload = doThisOnLoad; // 也就是上面的 window.onload 被這行蓋台了。

3. 所以建議你不要把 window.onload 和 body 的 onload 事件混用。
Posted by jaceju at 2007年11月15日 12:00
這麼清楚的解說
感激涕澪
Posted by Simon at 2007年11月15日 14:36

你好~請問以下用"///"所註解的程序內容是否正確,謝謝:

--- HTML頁面載入中:---
var Action2 = window.onload || function () {}; ///Action2 == null
window.onload = function () // Function B
{
Action2();
alert('Action 2');
}

var Action1 = window.onload || function () {}; ///Action1 == Functin B
window.onload = function() // Function A
{
Action1();
alert('Action 1');
}

var Action3 = window.onload || function () {}; ///Action3 == Functin A
window.onload = function () // Function C
{
alert('Action 3');
Action3();
}

--- 頁面載入完成,開始執行window.onload事件:---
因在頁面載入的最後,window.onload = Functin C
所以Function執行順序為:
C → 顯示'Action 3',由Action3() 呼叫 Functin A →
A → 由 Action1() 呼叫 Functin B →
B → Action2()是空值,顯示'Action 2' → B執行完回到A
A → 顯示'Action 1'

(顯示結果依序為:Action 3 → Action 2 → Action 1)
Posted by 俠雨 at 2008年02月19日 17:12

To 俠雨:

第一個 ///Action2 == null 是錯的, Action2 這時會是個空函式,而不是 null 。
Posted by jaceju at 2008年02月19日 17:29

謝謝你提供的好方法、解惑 ^^感恩
Posted by 俠雨 at 2008年02月19日 17:52