justinledouxweb
justinledouxweb

Reputation: 1357

Remove jQuery event where this is bound to the handler

I am trying to remove a jQuery event who's callback is bound with this. The problem is that .bind() creates a new function every time... so when I try removing the event, it is technically not the same function so it doesn't work.

I can't figure out how to keep the right this inside the callback in this case:

class Controller {
    open() {
        $('body').on('click', this.handleClick.bind(this));
    }

    close() {
        $('body').off('click', this.handleClick.bind(this));
    }
}

Upvotes: 1

Views: 139

Answers (3)

nem035
nem035

Reputation: 35481

Do the binding once in the constructor.

class Controller {

    constructor() {
      // overwrite handleClick() with its bound version
      this.handleClick = this.handleClick.bind(this);
    }

    open() {
        $('body').on('click', this.handleClick);
    }

    close() {
        $('body').off('click', this.handleClick);
    }
}

This way you overwrite the function once with the bound version that refers to the proper this and then attach/detach that function in your methods.

The additional advantage of doing things this way is that the binding is done only once, during instantiation, and then any future calls to open() or close() will use the same function that has the proper this.

Upvotes: 1

Karl-André Gagnon
Karl-André Gagnon

Reputation: 33870

jQuery has its own .bind polyfill. You can use $.proxy() to do what you want since it keep internaly a GUI. You can then unbind using the original function. jQuery is brillant enough:

class Controller {
    open() {
        $('body').on('click', $.proxy(this.handleClick, this));
    }

    close() {
        $('body').off('click', this.handleClick);
    }
}

Here an article that demonstrate it : http://www.bennadel.com/blog/2001-using-jquery-s-proxy-method-in-event-binding-and-unbinding.htm

jQuery keeps an internal counter to represent a "guid" (Globally Unique ID). When a function goes through the proxy() method, jQuery generates a new guid value and then applies that guid to both the core function as well as the resultant proxy function. It does this so that you can use the original function reference to unbind an event handler callback that has been proxied - jQuery uses the guid to test for function equivalence during the unbind process.

To see it in action, just explore this fiddle : https://jsfiddle.net/Lfqq88uj/1/

Upvotes: 1

eisbehr
eisbehr

Reputation: 12452

You can simply use jQuery namespaces:

class Controller {
    open() {
        $('body').on('click.myNamespace', this.handleClick.bind(this));
    }

    close() {
        $('body').off('click.myNamespace');
    }
}

Upvotes: 2

Related Questions