views:

56

answers:

3

Hi, I am trying to crate 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!

+2  A: 

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));
Andy E
You can also use `$.proxy()` here, e.g. `$.proxy(function(){ this.easeDragging(); }, this)` :)
Nick Craver
@Nick: A very useful jQuery function that I didn't know about, thanks :-)
Andy E
Excellent answer, I learn something new every day!
Totomobile
+2  A: 

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();
Nick Craver
A: 

Couldn't you bind to the document in the first place (inside the plugin) and then work out if the event is useful to you (happening on your element, or a child of your element).

You should use a namespace if you are binding to the document eg.

$(document).bind('mouseup.panorama', function() {
    ...
}
Blair McMillan