MicFin
MicFin

Reputation: 2501

Javascript "this" in a jquery event

How can I call functionOne correctly within the Jquery change function? "this" is no longer referencing the object.

NameSpace.object = {
  functionOne: function(){
     // stuff
  },
  functionTwo: function(){
     this.functionOne();  // this works correctly
  },
  functionThree: function(){
    $('input').change(function(){
       if ( $(this).val() > 1) {
         this.functionOne(); // this is no longer calling function one 
       }
    }
  }
}

Upvotes: 1

Views: 68

Answers (4)

dm03514
dm03514

Reputation: 55962

One way is to keep a reference to it using, conventionally calledself

NameSpace.object = {
  functionOne: function(){
     // stuff
  },
  functionTwo: function(){
     this.functionOne();  // this works correctly
  },
  functionThree: function(){
    var self = this;
    $('input').change(function(){
       if ( $(this).val() > 1) {
         self.functionOne(); // this is no longer calling function one 
       }
    }
  }
}

Under normal circumstances you could bind your callback to your object using this. But in this case I have no idea how it interacts with jquery's overriding of this to reference the element that triggered the callback...

Upvotes: 1

jfriend00
jfriend00

Reputation: 707326

Since you have two different values you want to use and jQuery is already putting one of them in this, you can just save the other value in a variable in a higher scope:

NameSpace.object = {
  functionOne: function(){
     // stuff
  },
  functionTwo: function(){
     this.functionOne();  // this works correctly
  },
  functionThree: function(){
    // save value if this so it can be used later in this scope
    var self = this;
    $('input').change(function(){
       if ( $(this).val() > 1) {
         self.functionOne();
       }
    }
  }
}

Or, since this is a statically named NameSpace.object, you could also just refer to that name directly:

NameSpace.object = {
  functionOne: function(){
     // stuff
  },
  functionTwo: function(){
     this.functionOne();  // this works correctly
  },
  functionThree: function(){
    $('input').change(function(){
       if ( $(this).val() > 1) {
         NameSpace.object.functionOne();
       }
    }
  }
}

Or, since jQuery provides a mechanism .change( [eventData], handler ) for passing data to an event handler, you can use that too:

NameSpace.object = {
  functionOne: function(){
     // stuff
  },
  functionTwo: function(){
     this.functionOne();  // this works correctly
  },
  functionThree: function(){
    $('input').change(this, function(e){
       if ( $(this).val() > 1) {
         e.data.functionOne();
       }
    }
  }
}

The jQuery mechanism is not my favorite here because I think the code that calls e.data.functionOne() is less obvious (the reader has to look back in the code to figure out what e.data is), but that's just my personal opinion for this situation.

Upvotes: 6

user4639281
user4639281

Reputation:

You can also use the optional eventData parameter of jQuery.change([eventData ],...).

By passing this to eventData your can access it from inside the handler through the event variable.

$('input').change(this,function(e){
    ...
    e.data.functionOne(); 
    ...
}

var NameSpace = {};
NameSpace.object = {
  functionOne: function(){
     // stuff
     alert("functionOne")
  },
  functionTwo: function(){
     this.functionOne();  // this works correctly
  },
  functionThree: function(){
    $('input').change(this,function(e){
       if ( $(this).val() > 1) {
         e.data.functionOne();  
       }
    })
  }
}

NameSpace.object.functionThree()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="number" />

Upvotes: 1

guest271314
guest271314

Reputation: 1

Try setting variable of NameSpace within functionThree , calling NameSpace.object.functionThree() to set change event at input element

var NameSpace = {};
NameSpace.object = {
  functionOne: function(){
     // stuff
     alert("functionOne")
  },
  functionTwo: function(){
     this.functionOne();  // this works correctly
  },
  functionThree: function(){
    var ns = this;
    $('input').change(function(){
       if ( $(this).val() > 1) {
        ns.functionOne(); // this is no longer calling function one 
       }
    })
  }
}

NameSpace.object.functionThree()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="number" />

Upvotes: 1

Related Questions