我正在制作游戏,我想抽象我的ui,并根据各种游戏状态绑定非绑定事件。但我无法弄清楚为什么这个事件没有被删除。似乎处理程序中的范围是正确的。
相关(剥离)js:
var controls = {
game : {
el : null,
cb : null,
bind : function(el, cb) {
this.el = el;
this.cb = cb;
this.el.addEventListener('click', this.handler.bind(this), true);
},
unbind : function() {
console.log('unbind');
this.el.removeEventListener('click', this.handler, true);
},
handler : function() {
this.cb();
this.unbind();
}
}
};
var manager = {
init : function() {
var c = document.getElementById('c');
controls.game.bind(c, this.action.bind(this));
},
action : function() {
console.log('c clicked');
}
};
manager.init();
然而,如果我以这种方式移除事件,它会起作用:
(...)
bind : function(el, cb) {
this.el = el;
this.cb = cb;
var self = this;
this.el.addEventListener('click', function() {
self.cb();
self.el.removeEventListener('click', arguments.callee, true);
}, true);
}
(...)
感谢
答案 0 :(得分:16)
.bind
会返回新功能。 this.handler.bind(this) !== this.handler
!你必须以某种方式存储对新函数的引用。
例如,将引用存储在变量中并使用闭包:
var handler = this.handler.bind(this);
this.el.addEventListener('click', handler, true);
this.unbind = function() {
this.el.removeEventListener('click', handler, true);
}
作为arguments.callee
的替代方案,您还可以为该函数命名:
this.el.addEventListener('click', function handler() {
self.cb();
self.el.removeEventListener('click', handler, true);
}, true);
答案 1 :(得分:7)
我建议使用the following:
,而不是使用需要更多内存的绑定var song = {
handleEvent: function (event) {
switch (event.type) {
case: "click":
console.log(this.name);
break;
}
},
name: "Yesterday"
};
songNode.addEventListener("click", song);
songNode.click(); // prints "Yesterday" into console
您可以使用具有obj
属性的对象handleEvent
作为任何DOM对象的处理程序来捕获其事件,并将事件处理程序的上下文设置为该对象obj
,而无需使用Function.prototype.bind
。
这样你也可以删除处理程序,所以
songNode.removeEventListener("click", song);