Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Plugin: Get the "this" object inside other functions

I am trying to create a panorama slider as a jQuery plugin, and I have the following code:

 $.fn.panorama = function(settings) {

    var myPanorama = this;
    ..

    this.mousedown(function(e){

       //do stuff 
       $(this).css... //this all work
    }


    //Call mouseup on document in case user lets go of mouse outside draggable object
$(document).mouseup(function(){
    $(myPanorama).easeDragging(); //works but probably not the way to do it
    this.easeDragging(); //ideal but refers to wrong object
 });

    }

My question is how do I refer to the this object inside the $(document).mouseup call?

Since it thinks this is the document itself and not the object attached to the plugin.

For now I am just making a variable and it works but there must be a better way!

thanks!

like image 539
Totomobile Avatar asked Aug 19 '10 19:08

Totomobile


2 Answers

Actually, the way you achieved it is the simplest way to do it - storing a reference to this:

var myPanorama = this;

// ...

    myPanorama.easeDragging();

Alternatively, you can use jQuery.proxy() to set the context of the function (thanks @Nick):

$(document).mouseup($.proxy(function(){
    this.easeDragging(); 
}, this));

The other way to do it is to use the ECMAScript 5th edition .bind() method, although you need to add this to the Function prototype for it to work in unsupported browsers:

// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}

Then you can use it in your code like so:

$(document).mouseup((function(){
    this.easeDragging(); 
}).bind(this));
like image 130
Andy E Avatar answered Nov 15 '22 14:11

Andy E


What you're doing is just fine (and entirely correct).

One optimization tip though, there's no need to wrap it again since it's already a jQuery object, you can just do this:

myPanorama.easeDragging();
like image 34
Nick Craver Avatar answered Nov 15 '22 15:11

Nick Craver