2013-10-27 102 views
2

我正在尋找答案,如果這是可能的,甚至是一個好主意。是否可以擴展EventTarget接口?

通常情況下,爲IE8和更早版本的修復,類似這樣的一個解決辦法是使用:

var addEvent = function(obj, e, cb) { 
    if(obj.attachEvent) { 
     return obj.attachEvent('on' + e, cb); 
    } else { 
     obj.addEventListener(e, cb, false); 
     return true; 
    } 
} 

,然後程序員總是使用addEvent代替addEventListener

有沒有什麼方法可以創建一個addEventListener函數,當它未定義時,它會環繞attachEvent

我想這是一個有點棘手,因爲該事件目標可以是DOM元素,文檔,或窗口,否則somethign。

回答

1

這取決於你想怎麼早去。在IE8上,您可以擴展Element.prototype以向所有HTML元素添加功能,這至少是工作量的90%。我相當肯定你不能這樣做在IE6(PrototypeJS不得不求助於擴展個體Element實例),我不記得有關IE7。除非你瞄準東亞市場,不過你可以忽略IE7和更早的版本。

這裏是如何做到這一點的例子:

(function() { 
    // Functions for IE 
    function stopPropagation() { 
    this.cancelBubble = true; 
    } 
    function preventDefault() { 
    this.returnValue = false; 
    } 
    function addEventUsingAttach(eventName, handler) 
    { 
    this.attachEvent("on" + eventName, function() { 
     var e = window.event; 
     e.stopPropagation = stopPropagation; 
     e.preventDefault = preventDefault; 
     handler.call(this, e); 
    }); 
    } 

    // Function to add `addEvent` to the given target object 
    function extendIt(target) 
    { 
    if (target.addEventListener) { 
     target.addEvent = Element.prototype.addEventListener; 
    } 
    else { 
     target.addEvent = addEventUsingAttach; 
    } 
    } 

    // Add it to `Element.prototype` if we have it 
    if (typeof Element !== "undefined" && 
     typeof Element.prototype !== "undefined") { 
    extendIt(Element.prototype); 
    } 

    // Add it to `window` and `document` (etc.) 
    extendIt(window); 
    extendIt(document); 
})(); 

Live Example | Source

然後您手動擴展其他EventTargets,如windowdocument(請參閱上面的代碼清單的末尾)。


原來的答覆:我原來是誤解你的問題是有關添加addEventListener,具體而言,IE8的,而實際上你的問題是很清楚有關補充說,但是添加自己的addEvent。我要離開這個答案在原地其他讀者:

這取決於你想怎麼早去。在IE8,您可以擴展Element.prototype添加addEventListener給它,這將通過頁面上的所有HTML元素被使用(見下文)。但是,添加的墊片不能支持捕獲階段,因爲直到他們本機支持addEventListener時,IE才支持它。我相當肯定你不能在早期版本(IE7,IE6)延長Element.prototype,PrototypeJS不得不回落到延長舊版本的IE瀏覽器的具體內容。但它在IE8中起作用。

擴展Element.prototype後,您必須手動擴展您提到的其他事件目標,但是擴展Element.prototype會完成大部分工作。

但是,如果你這樣做,你有第三方的腳本,提防他們可以採取正確實施addEventListeneer完成捕獲階段。

這是一個基本的墊片添加addEventListener到IE8:

(function() { 
    function stopPropagation() { 
    this.cancelBubble = true; 
    } 
    function preventDefault() { 
    this.returnValue = false; 
    } 
    if (typeof Element !== "undefined" && 
     typeof Element.prototype !== "undefined" && 
     !Element.prototype.addEventListener) { 
    Element.prototype.addEventListener = function(eventName, handler, useCapture) { 
     if (useCapture) { 
     throw "Browser doesn't support capturing phase"; 
     } 
     this.attachEvent("on" + eventName, function() { 
     var e = window.event; 
     e.stopPropagation = stopPropagation; 
     e.preventDefault = preventDefault; 
     handler.call(this, e); 
     }); 
    }; 
    } 
})(); 

Live Example | Source

+0

其實T.J.我最初的意思是我可以包含像IE8腳本這樣的東西(我完全忽略了它之前的版本),然後正常使用'addEventListener'(不需要在IE8中捕獲)。關鍵是避免使用一個獨特的名爲addEvent,而不是基於標準的香草JS。 – juuga

0

通常,功能可以由功能附連到對象

obj.addEventListener = function(/* args*/) { /* body */ } 

或由功能附連到對象constuctor

EventTarget.prototype.addEventListener = function(/* args*/) { /* body */ } 

的原型與前被添加到對象,只能在特定對象上調用添加的函數,而後者可讓您在所有對象上調用該函數,該對象將從該特定對象構造函數創建或將從其創建。

然而,

  • EventTargets是宿主對象,因此其是依賴於實現的功能是否可以被添加到這樣的對象。
  • EventTargets是宿主對象,因此它是否與實現有關,是否EventTarget.prototype實際存在並且與本機對象具有相同的含義。
  • 如果一個物體附着在EventTarget接口上,它很可能已經具有addEventListener函數。
  • 附加attachEvent的事件監聽器與添加了addEventListener的監聽器有不同的參數。

最後,嘗試使用JavaScript來支持更多標準的瀏覽器並不可行。

+0

即使在Chrome上,'typeof EventTarget'也是''undefined'',遠遠少於IE8。 –