Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to bind an object's method to an event

Is this the way to properly bind and event to an object's method in JavaScript using jQuery?

I've set up a little example code but the part I'm concerned of is the two-lines after the comment "is this ok?"

Of course, as the callback is a method of the object, I need the context to remain the same.

function MyPrototype(id) {

    this.id = id;
    this.sel = '#' + id;

    // *** IS THIS OK? ***
    $(this.sel).on('click', function(evt) {
        MyPrototype.prototype.mouseClick.call(this, evt); });
}

MyPrototype.prototype.mouseClick = function (evt) {

    // I want to use evt to get info about the event
    // I want use this to access properties and methods of the instance

    alert(this.id + ' was clicked');
}

myObject1 = new MyPrototype('myDiv1');
myObject2 = new MyPrototype('myDiv2');

Also, I may come to the necessity of unbinding the event from the specific function.

But the following is not working...

MyPrototype.prototype.unbindClick = function() {

    $(this.sel).off('click', function(evt) {
        MyPrototype.prototype.mouseClick.call(this, evt); });
}

myObject2.unbindClick();

Note that I'm passing an inline function as the event handler.

like image 988
Paolo Avatar asked Nov 04 '22 06:11

Paolo


1 Answers

Try jQuery.proxy:

function MyPrototype(id) {
    this.id = id;
    this.sel = '#' + id;

    // using jQuery.proxy:
    $(this.sel).on('click', $.proxy(this.mouseClick, this));

    // or Function.bind:
    // $(this.sel).on('click', this.mouseClick.bind(this));

    // or writing it out:
    /*
    var self = this;
    $(this.sel).on('click', function () {
      return self.mouseClick.apply(self, arguments);
    });
    */
}

MyPrototype.prototype.mouseClick = function(evt) {

    // I want to use evt to get info about the event
    // I want use this to access properties and methods of the instance

    console.log(this.id + ' was clicked');
};

var myObject1 = new MyPrototype('myDiv1');
var myObject2 = new MyPrototype('myDiv2');

http://jsbin.com/axokuz/1/


About the update to the question:

If you want to unbind a single event handler you would need the exact same handler function used while binding. Otherwise the whole event would be unbound. Neither the solution you added to the question nor $.proxy would help with that. There are some solutions, though:

  • keep a reference to the bound handler and use that while unbinding
  • use jQuery's Namespaced Events
like image 81
Yoshi Avatar answered Nov 08 '22 13:11

Yoshi