1

Note: This question uses jQuery but the question has nothing to do with jQuery!

Okay so I have this object:

var box = new BigBox();

This object has a method named Serialize():

box.AddToPage();

Here is the method AddToPage():

function AddToPage()
{
    $('#some_item').html("<div id='box' onclick='this.OnClick()'></div>");
}

The problem above is the this.OnClick() (which obviously does not work). I need the onclick handler to invoke a member of the BigBox class. How can I do this?

How can an object refer to itself in an event handler?

4 Answers 4

4

You should attach the handler using jQuery:

function AddToPage()
{
    var self = this;
    $('#some_item').empty().append(
        $("<div id='box'></div>")
            .click(function() { self.OnClick(someParameter); })
    );
}

In order to force the event handler to be called on the context of your object (and to pass parameters), you need to add an anonymous function that calls the handler correctly. Otherwise, the this keyword in the handler will refer to the DOM element.

Sign up to request clarification or add additional context in comments.

Comments

1

Don't add event handlers with inline code.

function AddToPage()
{
    $('#some_item').html("<div id='box'></div>");
    $('#box').click(this.OnClick);
}

EDIT:

Another way (avoids the extra select):

function AddToPage()
{
    var div = $('<div id="box"></div>'); // probably don't need ID anymore..
    div.click(this.OnClick);

    $('#some_item').append(div);
}

EDIT (in response to "how to pass parameters");

I'm not sure what params you want to pass, but..

function AddToPage()
{
    var self = this, div = $('<div></div>');
    div.click(function (eventObj) {
        self.OnClick(eventObj, your, params, here);
    });

    $('#some_item').append(div);
}

18 Comments

Ah. I see that this is probably a better option anyway considering the structure of the rest of the code. Thanks :)
Oh. And also, how do you pass parameters to the OnClick handler?
@George: OnClick will not be called in context. See my answer.
And your edit doesn't help. There's nothing in div.click(this.OnClick); that will preserve this (even if this is right when you call it, which is far from certain).
@Matt & @tvanfosson: It has nothing to do with parameters. It has to do with what this means within the call to the handler. @tvanfosson: Re "You might want to actually try it" I know this ground fairly well, actually: blog.niftysnippets.org/2008/03/mythical-methods.html blog.niftysnippets.org/2008/04/you-must-remember-this.html
|
1

In jQuery 1.4 you could use a proxy.

BigBox.prototype.AddToPage= function () {
    var div= $('<div>', {id: box});
    div.click(jQuery.proxy(this, 'OnClick');
    div.appendTo('#some_item');
}

You can also use a manual closure:

    var that= this;
    div.click(function(event) { that.OnClick(event); });

Or, most simply of all, but requiring some help to implement in browsers that don't yet support it (it's an ECMAScript Fifth Edition feature):

    div.click(this.OnClick.bind(this));

Comments

1

If you are using jQuery, then you can separate your code from your markup (the old seperation of concerns thing) like this

$(document).ready(function() {

  var box = new BigBox();

  $('#box').click(function() {
    box.serialize();
  });

});

You only need to add the click handler once for all divs with id of box. And because the click is an anonymous function, it gets the scope of the function it is placed in and therefore access to the box instance.

2 Comments

That does nothing to address his question about ensuring that this relates to an instance of BigBox (are people just not reading the question?).
Fair point, I forgot to include that once I started the reply.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.