1

Lately I've been trying to make an object in JavaScript with the following structure:

function colorDiv(div){
      this.div=div;
      this.div.bind("click",this.changeColor)
      this.changeColor(){
            this.div.css("background", "#FF0000");
      }
}

The problem is that the changeColor method cannot be called from the jQuery environment because this must refer to the current colorDiv object, so the bind method cannot work as expected. How can this be solved?

1
  • I believe the issue is that if you are going to use jquery methods like bind or css, you need to do it within the context of jquery, i.e. $(div).bind, $(div).css Commented Jul 14, 2011 at 1:09

2 Answers 2

4

There are a couple ways. The simplest is as follows:

function ColorDiv(div) {
      var that = this;

      that.div = div;
      that.div.bind("click", that.changeColor);

      that.changeColor = function () {
            that.div.css("background", "#FF0000");
      };
}

var colorDiv = new ColorDiv($("#my-div"));
$("#something-else").click(colorDiv.changeColor);

You save a reference to this in the variable that, which is just the name commonly used in the JavaScript world for exactly this purpose. Then you refer to that instead of this inside your changeColor method. (Note that I used that everywhere, just for consistency, even though the only place it actually makes a difference is inside the changeColor method.)


Another is to use the Function#bind method. You can either use it every time you call changeColor, like so:

var colorDiv = new ColorDiv($("#my-div"));
$("#something-else").click(colorDiv.changeColor.bind(colorDiv));

or you can use it in the ColorDiv class to ensure that all methods are bound correctly whenever they are called:

this.changeColor = (function () {
    this.div.css("background", "#FF0000");
}).bind(this);

As noted in the linked article, Function#bind is not supported in all browsers, so you'll need a shim like the one they give, or possibly a full-fledged ES5 shim.

Underscore.js has a bindAll function that could be useful here, too, especially with multiple methods:

_.bindAll(this);

Finally, it's worth noting you don't really need to do any of this in your particular example: just do

this.changeColor = function () {
    div.css("background", "#FF0000");
};

instead of what you have, i.e. reference the div variable passed in, instead of the reference stored in this.div, since they are the same thing.

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

1 Comment

Thanks dude, I was looking for something like the bind function. Sad that it doesn't work in 'not so new' browsers, but i'll give underscore a try ;)
0

Try setting as the first line of the method:

var self = this;

and then using self as needed.

this.div.bind("click",self.changeColor)

1 Comment

Careful: Although self is not a reserved word, it's a predefined variable that references the window object. See window.self

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.