是否可以扩展EventTarget接口? [英] Is it possible to extend the EventTarget interface?

查看:126
本文介绍了是否可以扩展EventTarget接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找答案,如果这是可能的,甚至是个好主意。

I'm looking for an answer if this is possible, or even a good idea.

通常,作为IE8和早期版本的修复,类似的解决方法使用它:

Usually, as a fix for IE8 and earlier versions, a workaround similar to this is used:

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

and then the programmer would always use addEvent instead of addEventListener.

是否有任何方式或点可以创建一个 addEventListener 函数,当它未定义时会回绕 attachEvent

Is there any way or point to create an addEventListener function that would wrap around the attachEvent when it is undefined?

我认为它有点棘手,因为EventTarget可以是DOM元素,文档或窗口,或者其他一些东西。

I imagine it's a bit tricky since the EventTarget can be a DOM element, the document, or the window, or somethign else.

推荐答案

这取决于你想要走多远。在IE8上,您可以扩展 Element.prototype 以向所有HTML元素添加功能,这至少是工作的90%。我很确定你不能在IE6中做到这一点(PrototypeJS不得不求助于扩展单个 Element 实例),我不记得IE7。除非您的目标是东亚市场,否则基本上可以忽略IE7及更早版本。

It depends on how far back you want to go. On IE8, you can extend Element.prototype to add features to all HTML elements, which is 90% at least of the work. I'm fairly sure you can't do that in IE6 (PrototypeJS had to resort to extending individual Element instances), I don't remember about IE7. Unless you're targeting east-Asian markets, you can basically ignore IE7 and earlier, though.

以下是您如何做到这一点的示例:

Here's an example of how you do that:

(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);
})();

实例 | 来源

然后你手动扩展其他EventTargets,如 window document (参见上面代码清单的末尾)。

Then you manually extend the other EventTargets, like window and document (see the end of the code listing above).

原始答案:我最初误读你的问题是关于添加 addEventListener ,特别是在IE8上,而事实上你的问题很明显关于添加,但添加你自己的 addEvent 。我将这个答案留给其他读者:

Original answer: I originally misread your question to be about adding addEventListener, specifically, on IE8, whereas in fact your question is quite clearly not about adding that, but adding your own addEvent. I'm leaving this answer in place for other readers:

这取决于你想要走多远。在IE8上,您可以扩展 Element.prototype 以向其添加 addEventListener ,并且所有HTML元素都将使用它在页面上(见下文)。你添加的填充程序不支持捕获阶段,因为IE在本机支持 addEventListener 之前不支持它。我很确定你不能在早期版本(IE7,IE6)上扩展 Element.prototype ,PrototypeJS不得不退回到扩展旧版IE的特定元素。但它适用于IE8。

It depends on how far back you want to go. On IE8, you can extend Element.prototype to add addEventListener to it, and that will be used by all HTML elements on the page (see below). The shim you add can't support the capturing phase, though, because IE didn't support it until they supported addEventListener natively. I'm fairly sure you can't extend Element.prototype on earlier versions (IE7, IE6), PrototypeJS had to fall back to extending specific elements for older versions of IE. But it works in IE8.

扩展 Element.prototype ,那么你必须手动扩展其他你提到的事件目标,但扩展 Element.prototype 完成大部分工作。

Having extended Element.prototype, then you'd have to manually extend the other event targets you mentioned, but extending Element.prototype does most of the work.

但如果你这样做,你包括第三方脚本,请注意他们可以假设正确实现 addEventListeneer 完成捕获阶段。

But if you do this and you include third-party scripts, beware that they may assume a correct implementation of addEventListeneer complete with the capturing phase.

这是将 addEventListener 添加到IE8的基本垫片:

Here's a basic shim for adding addEventListener to 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);
      });
    };
  }
})();

实例 | 来源

这篇关于是否可以扩展EventTarget接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆