如何在方法中添加事件侦听器时调用 removeEventLisener 并在 JavaScript 中的全局函数中调用

How to call removeEventLisener when addEventListener in a method and removeEventListener in a global function in JavaScript

本文关键字:调用 并在 removeEventLisener JavaScript 函数 全局 侦听器 方法 添加 事件      更新时间:2023-09-26
关于

类似的主题有很多问题和答案,但我觉得这是一个稍微不同的问题,另一个问题的答案并没有完全回答这个问题。我有一个构造函数,它的原型有一个addEventListener,用全局函数once调用。一次需要全局,但 addEventListener 需要在原型的方法中。如何删除事件侦听器,是放入还是once.bind(that) once removeEventListener 中的函数?

var once = function(event) {
  removeEventListener("keydown", /*something*/);
}
Chomp.prototype.playerMove = function() {
  var that = this;
  addEventListener("keydown", once.bind(that)); 
}

提前感谢! :)

在"非严格"模式下,你可以使用 arguments.callee 来获取对函数 once 的引用,受 once.bind(that) 约束。 不幸的是,在 ES5 严格模式下,该功能已被删除。

您可以调用一个单独的函数(必须命名,以便可以传递给removeEventListener),该函数处理事件处理程序的解除绑定。

Chomp.prototype.playerMove = function() {
    var that = this;
    var local_once = function() {
        removeEventListener('keydown', local_once);  // deregister this function
        return once.apply(that, arguments);          // invoke global "once"
    }
    addEventListener('keydown', local_once);
}

[太晚了 - 我刚刚意识到这当然需要修改once,但没有其他方法可以引用您的once.bind(that)生成的函数,除非它存储在您的原始once可以获取的地方。 此解决方案将"仅调用此一次"逻辑保留在 .playerMove 的本地 ]。

试试这个更新的代码:

var once = function(event) {
   document.body.removeEventListener("keydown", once);

}

Chomp.prototype.playerMove = function() {
    document.body.addEventListener("keydown", once); 
}

不能在once函数中使用once.bind(that)That在函数中一次都不知道。每个带有绑定的事件侦听器只能通过确切的函数调用来删除它是如何设置的。如果要在 remove 函数中引用once.bind(this),它将是与 add 函数中的包装器不同的包装器,并且不会删除事件。上面的代码将事件侦听器附加到body,并在用户按下密钥时将其删除。

另一种选择(更好)是将绑定的功能保存到播放器上

var once = function(event) {
   document.body.removeEventListener("keydown", this.keyDownEvent);

}

Chomp.prototype.playerMove = function() {
    this.keyDownEvent = once.bind(this);
    document.body.addEventListener("keydown", this.keyDownEvent); 
}