Dan Kanze
Dan Kanze

Reputation: 18595

calling javascript prototype method inside jquery bind

The code has been stripped down for simplicity and to address need:
I understand the methods will make no sense. I just want to know what is illegal and how I can use methods together in a fashion the best I can describe below.

The problem comes from the bindContentOverlay method:

this.setContentOverlayHeight is not a function
this.setContentHeight is not a function

Heres something like what im working with:
Any pointers on OOP using this type of style are also more than welcome.

$(document).ready(function(){
    var p = new Properties();
    p.bindContentOverlay();
});

var Properties = function()
{
    this.initialize();
}

Properties.prototype.initialize = function()
{
    this.menu = {"#power" : null,"#services" : "#services_menu","#cashback" : null,"#schedule" : "#schedule_menu"};
    this.a = 22;
    this.b = 33;
}

Properties.prototype.getHeights = function()
{
    this.initialize();
    this.q = this.a;
    this.w = this.b;
}

Properties.prototype.setContentOverlayHeight = function()
{   
    this.getHeights();
    alert(this.q);
}

Properties.prototype.setContentHeight = function()
{
    this.getHeights();
    alert(this.w);
}


Properties.prototype.bindContentOverlay = function()
{
    for(var i in this.menu)
    {
        (function(x, y) {
             $(x+','+y).hover(
                 function () {
                    console.log(x);
                    this.setContentOverlayHeight();
                 },
                 function () {
                    this.setContentHeight();
                    console.log(y);
                 }
            );
        })(i, this.menu[i]);
    }   
}

Upvotes: 0

Views: 1931

Answers (2)

Alex Wayne
Alex Wayne

Reputation: 187014

Whenever you define a function in a function, you will likely lose context (the value of this).

The problem is how you've written the bindContentOverlay method. When those deepest functions execute, this isn't what you expect.

The simplest way to prevent this is to save this to a local variable and use that instead.

Properties.prototype.bindContentOverlay = function()
{
    // Save "this" to local var, and use the var instead for any inner functions.
    var instance = this;

    for(var i in this.menu)
    {
        (function(x, y) {
             $(x+','+y).hover(
                 function () {
                    console.log(x);
                    instance.setContentOverlayHeight();
                 },
                 function () {
                    instance.setContentHeight();
                    console.log(y);
                 }
            );
        })(i, instance.menu[i]);
    }   
}

Upvotes: 1

Alnitak
Alnitak

Reputation: 339786

Your this in the hover callbacks refers to the element being hovered over, not the current Properties object.

The simplest fix is to bind a local reference to this at the top of .bindContentOverlay:

Properties.prototype.bindContentOverlay = function()
{
    var self = this;
    ...
}

and then use self.setContentOverlayHeight() in the callbacks.

Upvotes: 2

Related Questions