2010-04-17 191 views
66

我在想如何正確使用addEventListener分別是attachEvent正確使用addEventListener()/ attachEvent()?

window.onload = function (myFunc1) { /* do something */ } 

function myFunc2() { /* do something */ } 

if (window.addEventListener) { 
    window.addEventListener('load', myFunc2, false); 
} else if (window.attachEvent) { 
    window.attachEvent('onload', myFunc2); 
} 

// ... 

function myFunc1() { /* do something */ } 

if (window.addEventListener) { 
    window.addEventListener('load', myFunc1, false); 
} else if (window.attachEvent) { 
    window.attachEvent('onload', myFunc1); 
} 

function myFunc2() { /* do something */ } 

if (window.addEventListener) { 
    window.addEventListener('load', myFunc2, false); 
} else if (window.attachEvent) { 
    window.attachEvent('onload', myFunc2); 
} 

// ... 

這是跨瀏覽器的安全或者我應該更好地與像這樣去:

function myFunc1(){ /* do something */ } 
function myFunc2(){ /* do something */ } 
// ... 

function addOnloadEvent(fnc){ 
    if (typeof window.addEventListener != "undefined") 
    window.addEventListener("load", fnc, false); 
    else if (typeof window.attachEvent != "undefined") { 
    window.attachEvent("onload", fnc); 
    } 
    else { 
    if (window.onload != null) { 
     var oldOnload = window.onload; 
     window.onload = function (e) { 
     oldOnload(e); 
     window[fnc](); 
     }; 
    } 
    else 
     window.onload = fnc; 
    } 
} 

addOnloadEvent(myFunc1); 
addOnloadEvent(myFunc2); 
// ... 

和:說myfunc2是IE 7只。如何相應地修改正確/首選的方法?

+0

你可能不喜歡我這樣說,但你爲什麼不用一個框架來處理這些問題呢? – Pointy 2010-04-17 04:18:59

+0

我會,但我不能在這種情況下。所以,你能幫我解決這個問題嗎? – ginny 2010-04-17 04:30:09

+0

@ginny看看我的答案。如果您需要進一步的解釋,請告訴我。 – hitautodestruct 2012-11-25 13:39:14

回答

6

還有人打這個討論,沒有找到他們正在尋找結賬答案:
http://dustindiaz.com/rock-solid-addevent
這是最優雅的解決方案,我發現對於我們這些對使用框架的限制之一。

function addEvent(obj, type, fn) { 

    if (obj.addEventListener) { 
    obj.addEventListener(type, fn, false); 
    EventCache.add(obj, type, fn); 
    } else if (obj.attachEvent) { 
    obj["e" + type + fn] = fn; 
    obj[type + fn] = function() { 
     obj["e" + type + fn](window.event); 
    } 
    obj.attachEvent("on" + type, obj[type + fn]); 
    EventCache.add(obj, type, fn); 
    } else { 
    obj["on" + type] = obj["e" + type + fn]; 
    } 

} 

var EventCache = function() { 

    var listEvents = []; 
    return { 
    listEvents: listEvents, 
    add: function (node, sEventName, fHandler) { 
     listEvents.push(arguments); 
    }, 
    flush: function() { 
     var i, item; 

     for (i = listEvents.length - 1; i >= 0; i = i - 1) { 
     item = listEvents[i]; 
     if (item[0].removeEventListener) { 
      item[0].removeEventListener(item[1], item[2], item[3]); 
     }; 

     if (item[1].substring(0, 2) != "on") { 
      item[1] = "on" + item[1]; 
     }; 

     if (item[0].detachEvent) { 
      item[0].detachEvent(item[1], item[2]); 
     }; 

     item[0][item[1]] = null; 
     }; 
    } 
    }; 
}(); 

addEvent(window,'unload',EventCache.flush); 
116

二者的使用是類似的,但二者採取一個稍微不同的語法的事件參數:

的addEventListener(mdn reference):

obj.addEventListener('click', callback, false); 

function callback(){ /* do stuff */ } 

Events listaddEventListener

的attachEvent(msdn reference):

obj.attachEvent('onclick', callback); 

function callback(){ /* do stuff */ } 

Events listattachEvent

參數

對於兩者的參數如下方法:
1.事件類型。
2.函數一旦觸發事件就會調用。
3. (僅限於addEventListener如果爲true,表示用戶希望啓動capture

說明

這兩種方法都用於實現將事件附加到元素的相同目標。
不同之處在於,attachEvent只能在舊trident渲染引擎中使用( IE5 + IE5-8 *)和addEventListener是在大多數其他瀏覽器實現的W3標準(FF,Webkit的,歌劇,IE9 +) 。

由於Smitty建議你應該看看這個Dustin Diaz addEvent爲一個堅實的跨瀏覽器實現而不使用框架。

對於固定的跨瀏覽器事件支持,包括使用Diaz解決方案無法獲得的規範化,請使用framework

*爲了向後兼容,IE9-10支持這兩種方法。

感謝Luke Puplett指出已從IE11中刪除。

+0

@CamiloMartin如果你以後得到這樣的評論,那麼總是有一個好的答案,謝謝:) – hitautodestruct 2012-09-10 08:08:22

+12

'addEventListener'也支持IE9 +。 – MrWhite 2012-11-25 12:17:08

+0

attachEvent已在IE11中刪除,因此檢測IE並使用此API的代碼現在將失敗。我還沒有看到發生這種情況,但我注意到,從IE11欺騙IE10代理字符串可能會導致腳本錯誤。 – 2013-11-21 13:45:02