你很想要單一標準,但製作瀏覽器的人才不理你咧~

在處理一個網頁上某個 element 的事件時,常會去寫一個 event handler,然後讓該 element 的 onXXX event 被觸發時,會去 call 你寫的 event handler,但這樣子的動作,至少在 IE 與 Firefox 中是有一點不太一樣的..

假設我有個 div element,我希望當滑鼠點到這個 div 的時候,秀出滑鼠的座標點,乍想之下可能會這樣寫:

<script type="text/javascript">
  function handleClick(e) {
    var mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
    var mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
    alert(mouseX + ", " + mouseY);
  }

  function init() {
    var elem = document.getElementById('sandbox');
    elem.onclick = handleClick;
  }
</script>
<body onload="init();">
...
<div id="sandbox">
...
</div>
...
</body>

這樣的 HTML+JavaScript 跑在 firefox 上面是沒有問題的,但在 IE 上就會跟你抱怨 e 沒有定義。但因為用 IE 的人實在是太多了,不得不照顧一下 IE 的使用者,所以要改寫 handleClick 這個 function:

function handleClick(e) {
    if (e == undefined) var e = window.event;
    var mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
    var mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
    alert(mouseX + ", " + mouseY);
}

因為在 IE 裡,觸發 onXXX event 的時候並不會把 event object 傳到 function 裡,所以當我們發現 e 是 undefined 時,就補一個宣告給它囉。

要同時照顧不同瀏覽器還真是一件蠻辛苦的事..

 

歷史上的今天

目前有 10 則留言
  1. Avatar Avenger.Bevis:

    呵呵 看來 你的這句代碼 不是自己剛寫的 而是從某個地方Co來的
    ::HLIGHT_BLOCK_1::
    因為你在最后加上IE支持的時候 用的是e == undefined
    要依你上邊的做法 應該這樣寫
    ::HLIGHT_BLOCK_2::

    不是么

  2. Avatar ericsk:

    Avenger:
    我不太懂你的意思耶, 不好意思 @@

  3. Avatar Avenger.Bevis:

    看來我得重發一下代碼了 代碼外加上[code]結果顯示::HLIGHT_BLOCK_2::

    function handleClick(e) {
    e = e || event; // (event == window.event) is true on IE

  4. Avatar Avenger.Bevis:

    我一直在RSS你的博客
    你寫的東東都蠻不錯的 我很喜歡
    恩 干巴爹!

  5. Avatar ericsk:

    @Avenger
    你寫得沒錯, 不過 undefined 那裡是我自己寫的 Orz

  6. Avatar ericsk:

    @Avenger: 感謝支持 :)

  7. Avatar racklin:

    在實務上, 還可以加一個 Wrapper Function 來處理相容性的問題, 並可以提供額外的資料傳給您的 Event.
    function _Event_Callback(bind, data) {
    return function (event) {
    event = event || window.event;
    if( data != undefined ) event.data = data;
    var args = [].slice.call( arguments, 1 );
    args.unshift( event );
    return bind.apply( this, args );
    };
    }
    所以你原例子中的 onclick 可以寫成:
    elem.onclick = _Event_Callback(handleClick);

    如果想在 runtime 傳入資料, 則可寫成:
    elem.onclick = _Event_Callback(handleClick, ‘racklin’);
    這樣在 handleClick(e) 中, e.data 等於 racklin.

  8. Avatar ericsk:

    racklin: 非常感謝你補完 :D

  9. University Update - Firefox - [JS] JavaScript ?? onXXX event ???:

    [...] Contact the Webmaster Link to Article firefox [JS] JavaScript ?? onXXX event ??? » Posted at ericsk’s blog on Thursday, [...]

  10. Avatar Sean:

    我通常這麼做,程式碼比較簡潔,又可相容IE/FF:

    function handleClick(event) {
    var mouseX = event.pageX …..

我要留言
(必填)
(必填)