类似的主题有很多问题和答案,但我觉得这是一个稍微不同的问题,另一个问题的答案并没有完全回答这个问题。我有一个构造函数,它的原型有一个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);
}