In JavaScript, what is the best way to remove a function added as an event listener using bind()?
Example
(function(){
// constructor
MyClass = function() {
this.myButton = document.getElementById("myButtonID");
this.myButton.addEventListener("click", this.clickListener.bind(this));
};
MyClass.prototype.clickListener = function(event) {
console.log(this); // must be MyClass
};
// public method
MyClass.prototype.disableButton = function() {
this.myButton.removeEventListener("click", ___________);
};
})();
The only way I can think of is to keep track of every listener added with bind.
Above example with this method:
(function(){
// constructor
MyClass = function() {
this.myButton = document.getElementById("myButtonID");
this.clickListenerBind = this.clickListener.bind(this);
this.myButton.addEventListener("click", this.clickListenerBind);
};
MyClass.prototype.clickListener = function(event) {
console.log(this); // must be MyClass
};
// public method
MyClass.prototype.disableButton = function() {
this.myButton.removeEventListener("click", this.clickListenerBind);
};
})();
Are there any better ways to do this?
We had this problem with a library we could not change. Office Fabric UI, which meant we could not change the way event handlers were added. The way we solved it was to overwrite the
addEventListener
on theEventTarget
prototype.This will add a new function on objects
element.removeAllEventListers("click")
(original post: Remove Click handler from fabric dialog overlay)
It's been awhile but MDN has a super explanation on this. That helped me more than the stuff here.
MDN :: EventTarget.addEventListener - The value of "this" within the handler
It gives a great alternative to the handleEvent function.
This is an example with and without bind:
A problem in the example above is that you cannot remove the listener with bind. Another solution is using a special function called handleEvent to catch any events:
Although what @machineghost said was true, that events are added and removed the same way, the missing part of the equation was this:
See Does bind() change the function reference? | How to set permanently?
So, to add or remove it, assign the reference to a variable:
This works as expected for me.
It doesn't matter whether you use a bound function or not; you remove it the same way as any other event handler. If your issue is that the bound version is its own unique function, you can either keep track of the bound versions, or use the
removeEventListener
signature that doesn't take a specific handler (although of course that will remove other event handlers of the same type).(As a side note,
addEventListener
doesn't work in all browsers; you really should use a library like jQuery to do your event hook-ups in a cross-browser way for you. Also, jQuery has the concept of namespaced events, which allow you to bind to "click.foo"; when you want to remove the event you can tell jQuery "remove all foo events" without having to know the specific handler or removing other handlers.)For those who have this problem while registering/removing listener of React component to/from Flux store, add the lines below to the constructor of your component:
Here is the solution: