[JavaScript] window.onresize 連續觸發的問題
今天遇到了一個怪異的問題,就是在 IE6 底下 window 的 onresize 這個事件竟然會在視窗大小沒有改變的情況下被連續觸發;試了一下 Firefox 和 IE7 都沒有這個問題,所以我便懷疑是 IE6 有實作上的錯誤。
為了查證,我 Google 了一下,找到了以下這篇文章:
IE Fires Onresize When Body Resizes
原來 IE6 會在 body 被 resize 時,同時觸發 window 的 resize 事件。
不過 body 什麼時候會被 resize 呢?通常就是利用 display 來顯示或隱藏元素的時候,例如:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>window.onresize</title> <script type="text/javascript"> var link = null; var block = null; var resizeWindow = function () { alert('resized'); }; window.onload = function () { link = document.getElementById('link'); block = document.getElementById('block'); link.onmouseover = function () { block.style.display = 'block' }; link.onmouseout = function () { block.style.display = 'none' }; window.onresize = resizeWindow; }; </script> </head> <body> <a href="window.onresize.html" id="link">Link</a> <div id="block" style="display:none;"> <p>Show something.</p> </div> </body> </html>
這時候當滑鼠移到 Link 上時,因為元素會有消長,所以 body 的 resize 就會被觸發 (也即 reflow 這個觀念) ,只是這時候 IE6 就會很雞婆地一起觸發 window 的 resize 事件,而且會一直連續觸發;如果這時我們在 window.onresize 有設定要處理某些東西的話 (例如上面的 resizeWindow 函式) ,就會使得真正的 mouseover 和 mouseout 事件無法正常動作。
而我會遇到這個狀況是因為我需要在 window.onresize 裡處理一些排版上的問題,也就是在視窗大小變化後,有些透過 JavaScript 來調整寬度的選單就需要重新調整。但是這時如果連續觸發了 window 的 resize 事件,就會造成整個程式執行起來頓頓的。
還好上面找到的文章提供了一個解法,那就是判斷 document.documentElement.clientHeight 是不是有被改變了。所以我只要把 resizeWindow 這個事件改成以下的樣子就可以了:
var currentClientHeight = 0; var resizeWindow = function () { if (currentClientHeight != document.documentElement.clientHeight) { alert('resized'); } currentClientHeight = document.documentElement.clientHeight; };
雖然 window 的 resize 事件還是會被連續觸發,但是至少觸發時所需要執行的動作減少了,這樣就不會讓程式執行起來感覺頓頓的了。
近期迴響