2

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

通常,作为 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

我想这有点棘手,因为 EventTarget 可以是 DOM 元素、文档、窗口或其他东西。

4

2 回答 2

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

实例| 资源

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


原始答案:我最初误认为您的问题是关于添加addEventListener,特别是在 IE8 上,而实际上您的问题显然不是添加,而是添加您自己的addEvent. 我将这个答案留给其他读者:

这取决于你想回多远。在 IE8 上,您可以扩展Element.prototype以添加addEventListener到它,页面上的所有 HTML 元素都将使用它(见下文)。但是,您添加的 shim 不支持捕获阶段,因为 IE 在原生支持之前不支持它addEventListener。我很确定您不能Element.prototype在早期版本(IE7、IE6)上进行扩展,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);
      });
    };
  }
})();

实例| 资源

于 2013-10-27T10:07:36.007 回答
0

通常,可以通过将函数附加到对象来将函数添加到对象

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

或通过将函数附加到对象构造函数的原型

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

对于前者,添加的函数只能在特定对象上调用,而后者允许您在从该特定对象构造函数创建或将创建的所有对象上调用该函数。

然而,

  • EventTargets 是宿主对象,因此是否可以将函数添加到此类对象取决于实现。
  • EventTargets 是宿主对象,因此它取决于实现是否EventTarget.prototype实际存在并且与本机对象具有相同的含义。
  • 如果一个对象遵循EventTarget接口,它很可能已经有一个addEventListener功能。
  • 附加的事件侦听器具有与attachEvent添加的不同的参数addEventListener

最后,尝试使用 JavaScript 让具有糟糕 DOM 的浏览器支持更多符合标准的浏览器是不可行的。

于 2013-10-27T10:14:48.443 回答