addEventListener的非法调用

3
使用jQuery,您可以在任何jQuery对象上使用 .on()/.off()/.trigger() 方法,从而强大地访问事件系统。我正在尝试在原生JavaScript中实现类似的功能,但我一直遇到 "TypeError: Illegal Invocation" 的问题。我知道这个错误通常是指当方法需要一个特定的this引用时丢失它。使用.apply.call 似乎通常能解决问题,但我仍然遇到问题。
具体来说,我正在尝试创建一个启用事件的“类”,然后我可以从其他类中扩展它,从而为我提供一种在非DOM对象上监听和触发事件的方法。 (是的,我知道JS没有真正的类。我正在使用CoffeeScript,那是那里使用的语法糖。)以下是“类”函数,它创建了一个新对象,该对象具有与传递给构造函数的对象相同的属性和值,并提供了三个方法,这些方法应用自EventTarget.prototype 。如果您能指导我如何使其正常工作,我将不胜感激!
EventEnabled = (function() {
  function EventEnabled(obj) {
    var key, val;
    for (key in obj) {
      val = obj[key];
      this[key] = val;
    }
  }

  EventEnabled.prototype.addEventListener = function() {
    return EventTarget.prototype.addEventListener.apply(this, arguments);
  };

  EventEnabled.prototype.removeEventListener = function() {
    return EventTarget.prototype.removeEventListener.apply(this, arguments);
  };

  EventEnabled.prototype.dispatchEvent = function() {
    return EventTarget.prototype.dispatchEvent.apply(this, arguments);
  };

  return EventEnabled;

})();

当我尝试在EventEnabled的实例上调用这三种方法之一时,我会收到一个"TypeError: Illegal Invocation"的错误提示。感谢您对此提供的任何见解!

1
addEventListener(以及相关函数)希望你将一个 DOM 元素作为this传递进去,而不是你的EventEnabled类的实例。 - gen_Eric
是的,你只能在 DOM 元素上调用 addEventListener。jQuery 允许你将事件“绑定”到任何 jQuery 对象上,但这是因为它只是将函数存储在实例中,并在触发时调用它。它仅在 DOM 元素上使用 addEventListener - gen_Eric
1
@RocketHazmat 我明白了,那真是太糟糕了。我注意到在混合使用jQuery / vanilla事件监听器时会出现一些奇怪的问题,如这里所示。我想我会想出其他的办法,谢谢你的帮助。 - nickb
可能是如何使用JavaScript EventTarget?的重复问题。 - Bergi
@Bergi如果您想回答EventTarget是一个接口而不是构造函数,我认为这对于那些考虑走我走过的同样道路的人会很有帮助,我将非常乐意接受这个答案。 - nickb
显示剩余2条评论
1个回答

8

EventTarget只是一个在本地DOM对象上实现的接口,而不是javascript可用的构造函数。虽然它可能在全局范围内可用,但你不能用它来实例化。

此外,只能在本地实现了该接口的对象(如DOM元素)上应用其方法,而不能在EventEnabled构造函数的任意实例上应用。你需要创建一个内部节点,或者实现自己的事件分派系统(如果你不想使用任何可用的库)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接