Removing event listener which was added with bind

takfuruya picture takfuruya · Jul 19, 2012 · Viewed 58.5k times · Source

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?

Answer

Ben picture Ben · Apr 4, 2014

Although what @machineghost said was true, that events are added and removed the same way, the missing part of the equation was this:

A new function reference is created after .bind() is called!

See Does bind() change the function reference? | How to set permanently?

So, to add or remove it, assign the reference to a variable:

var x = this.myListener.bind(this);
Toolbox.addListener(window, 'scroll', x);
Toolbox.removeListener(window, 'scroll', x);

This works as expected for me.