33

I have a quick question regarding the proper way to access Javascript class member variables from inside of an event handler that class uses. For example:

function Map() {
    this.x = 0;
    this.y = 0;

    $("body").mousemove( function(event) {
        this.x = event.pageX;     // Is not able to access Map's member variable "x"
        this.y = event.pageY;     // Is not able to access Map's member variable "y"
    });
}

Rather than changing the member variable of the "Map" class, the "this.x" in the event handler tries to affect the "x" member variable of the element that triggered the event. What is the proper way to access the member variables of the "Map" class from within the event handlers?

Any help would be greatly appreciated - I've been sort of scratching my head at this one.

Cheers, Charlie

3 Answers 3

53

Since this changes in an event context (points to global usually), you need to store a reference to yourself outside of the event:

function Map() {
    this.x = 0;
    this.y = 0;
    var _self = this;
    $("body").mousemove( function(event) {
        _self.x = event.pageX;     // Is now able to access Map's member variable "x"
        _self.y = event.pageY;     // Is now able to access Map's member variable "y"
    });
}
Sign up to request clarification or add additional context in comments.

2 Comments

The this value on event handlers usually points to the DOM element where the handler is bound, in this case this === document.body.
Thank you very much for the quick response! This works like a charm, and is very clean too. Thanks!
14

The solution that Matt gave it probably the way to go.

Just thought I'd point out that you can pass data via the event object like this:

function Map() {
    this.x = 0;
    this.y = 0;

// Pass object with data-------------v
    $("body").bind('mousemove', {ths: this}, function(event) {
            // access this via event.data
        event.data.ths.x = event.pageX;
        event.data.ths.y = event.pageY;     
    });
}

This is just for the info. It is really not a practical application. Matt's reference to a local variable makes more sense.

2 Comments

I didn't know that you could do that - it's interesting, though. You're right, it's not a very practical application right here, but it may just come in handy in the future. Thanks for the tip!
I found myself in a situation where this was the only way out - thanks!
0

You can also use JQuery.proxy, to create a proxy function with its context. You can than bind the proxy to events.

Here is an example:

var init_handler  =  $.proxy(this.init, this);
$('#page_id').bind('pageinit', init_handler);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.