Reputation: 1259
I have a special scenario described as short as possible in this pen: http://codepen.io/tuelsch/pen/rVRRNm?editors=101
This article (Adding and Removing Event Listeners with parameters) pointed me in the right direction but has a different setup.
I like to have a custom JS object (Film) which can add and remove event handler on its link
property (a DOM element).
I'm stuck with the removeEvent
function on line 18. What is the correct second argument for the removeEventListener
function in this case?
Instead of adding and removing the event listener, it just keeps adding event listeners, as can be observed in the console, where the result of line 8 is logged.
The solution should be plain vanilla JavaScript, ES5 compatible and intended to run in the browser (IE9+).
Upvotes: 0
Views: 7102
Reputation: 9813
// Add the event handler
Film.prototype.bindEvent = function () {
// This ensure that the binded event can be removed by removeEvent
// even if you call bindEvent many times.
if (!this._bindedEvent) {
this._bindedEvent = this.eventHandler.bind(this);
this.link.addEventListener('click', this._bindedEvent);
}
}
Then remove that:
// Remove the event handler
Film.prototype.removeEvent = function () {
if (this._bindedEvent) {
this.link.removeEventListener('click', this._bindedEvent);
this._bindedEvent = null;
}
}
2 . Another way is to override eventhandler
in constructor:
// The test class definition
var Film = function () {
this.link = document.getElementById('film');
// This first find if self has attr eventHandler, and keep lookup to its prototype.
// Then createa binded version of eventhandler and set to this's attr.
// So when you try to access `this.eventHandler`, it'll be the binded version instead of Prototype's
this.eventHandler = this.eventHandler.bind(this);
}
Then you can just use
// Add the event handler
Film.prototype.bindEvent = function () {
this.link.addEventListener('click', this.eventHandler);
}
// Remove the event handler
Film.prototype.removeEvent = function () {
this.link.removeEventListener('click', this.eventHandler);
}
To add and remove it.
Upvotes: 3
Reputation: 191976
When you use .bind(this)
as you do here: this.link.addEventListener('click', this.eventHandler.bind(this));
you actually get a new function. When you try to remove it, you use the original handler, and the remove can't find the binded handler.
From MDN:
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
To fix that use the bind when you define the handler (codepen - the handler is removed after 3 seconds):
// The event handler to add and remove
Film.prototype.eventHandler = function () {
console.log('handled');
}.bind(Film);
// Add the event handler
Film.prototype.bindEvent = function () {
this.link.addEventListener('click', this.eventHandler);
}
// Remove the event handler
Film.prototype.removeEvent = function () {
this.link.removeEventListener('click', this.eventHandler);
}
Upvotes: 1