Don P
Don P

Reputation: 63547

jQuery use an object's method as an event handler

I have an object. It initializes a button to alert "Hello!" when it is clicked. Why won't this work?

jsfiddle: http://jsfiddle.net/kUT52/1/

HTML

<button>Test</button>

JS

var MyObject = {
  testValue: "Hello!",

  testFunction: function() {
    alert(this.testValue);
  },

  init: function(button) {
    button.click(this.testFunction());
  }
}

$(document).ready(function(){
  var buttonInstance = new MyObject();
  var button = $('button');
  buttonInstance.init(button);
});

Upvotes: 6

Views: 2264

Answers (3)

adeneo
adeneo

Reputation: 318162

That's an object literal, and you'd normally use it like so :

var MyObject = {
    testValue: "Hello!",

    testFunction: function() {
        alert(MyObject.testValue);
    },

    init: function(button) {
        button.on('click', this.testFunction);
    }
}

var button = $('button');
MyObject.init(button);

FIDDLE

or passing the object:

var MyObject = {
    testValue: "Hello!",

    testFunction: function(e) {
        alert(e.data.obj.testValue);
    },

    init: function(button) {
        button.on('click', {obj: this}, this.testFunction);
    }
}

var button = $('button');
MyObject.init(button);

FIDDLE

Upvotes: 1

Guffa
Guffa

Reputation: 700152

For two reasons:

  • You are using testFunction() instead of testFunction when you bind the event, so you will be calling the function and binding the (undefined) return value.

  • When you use a method as a function, it's no longer attached to the object, so the context will not be the object when the callback is called, but the global window object.

Use the proxy method to make a function that calls the method with the right context:

button.click($.proxy(this.testFunction, this));

Upvotes: 4

Felix Kling
Felix Kling

Reputation: 816262

Whenever you put () behind a function reference, you are executing the function. You have to pass the function reference to .click, not what the function returns (unless the function returns a function that you want to use as event handler).

Example:

button.click(this.testFunction);

But now you have another problem: Inside the function, this will refer to the DOM element and not to the object, so accessing this.testValue will return undefined.

You can use jQuery's $.proxy function to fix this:

button.click($.proxy(this.testFunction, this));

Now this will refer to the object, and you can get a reference to the clicked element via event.target.

Upvotes: 12

Related Questions