I am working on a game and I would like to abstract my ui, and bind unbind events based on various game states. But I can't figure out why this event is not being removed. It seems the scope is correct in the handler.
relevant (stripped down) 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();
And yet if I remove the event this way it works:
(...)
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);
}
(...)
thanks
.bind
returns a new function.this.handler.bind(this) !== this.handler
! You would have to store a reference to the new function somehow.For example, storing a reference in a variable and using a closure:
As alternative to
arguments.callee
, you could also give the function a name:Instead of playing with binding which also requires more memory I'd recommend using the following:
You can use an object
obj
that hashandleEvent
property as a handler on any DOM object to catch its events and have event handler's context set to that objectobj
without the use ofFunction.prototype.bind
.That way you can also remove handlers, so