2013-10-27 73 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。 –