steps
steps

Reputation: 804

Parent "$(this)" in jquery's scope

I have a $.fn.sample = function() called by, let's say $('#example').sample(); so inside the function I could use "this" into it's scope:

$.fn.sample = function(){
   console.log($(this).width()); 
} //In this case, it would log the width of #example 

But let's say I call a hover function into another element, like this

$.fn.sample = function(){ 
  console.log($(this).width()); 
  $('#other').hover(function(){
    //Here, $(this) will refer to #other
  });
}

So, inside the hover function "$(this)" will refer to #other, is there a way to use the "parent" $(this)? In this case, the "#example" inside this hover function?

Upvotes: 3

Views: 490

Answers (8)

Michael
Michael

Reputation: 502

The previous solutions to use a named variable are the fix to your particular question. So go with one of those. ClintNash's answer was particularly insightful.

However, this leads to the fact that most people don't understand JavaScript scope and what a closure is/does.

For an in depth read on JavaScript closures, scope etc. see this blog post (not mine): http://jibbering.com/faq/notes/closures/

Upvotes: 2

Nash Worth
Nash Worth

Reputation: 2574

The answer is yes, but not with parent.

A common solution for your question is to use a 'that' variable:

$.fn.sample = function(){ 
  console.log($(this).width());

  var that = $(this);             // <-- good pattern for traversing scope.
       
  $('#other').hover(function(){
    
    //Here, that will refer to the parent.
  });

}

I believe this was originally proposed by Douglas Crockford, but I am not certain of the origin. The link will give the technical details, but the usage turns out to be very important for 'private data members'.

Another very important point on Best-Practice...

I really recommend using the pattern but not calling the variable 'that'.

Here is why:

It is not so important to know -> where a variable came from, but -> what it is. In practice, a that can be coming from a wrapping scope many lines of code away from the current line in question. From a maintainability standpoint, it is a waste of time to try and figure out what 'that' is, and even more frustrating if it is not even known what 'this' is. Instead, we should just call it what it is and let the scope be what it is.

For example,

var button_container; //instead of that.

Also, others are using the naming convention of adding a dollar sign.

var $name;

This is ok, but can be confusing. It is worth mentioning that it indicates the object is a jQuery object.

Hope that helps.

Upvotes: 3

Mark Broadhurst
Mark Broadhurst

Reputation: 2695

I would go with any of the other options given here but as an alternative you can use the apply method of a function in order to set this to what you want.

Upvotes: 0

samisadaka
samisadaka

Reputation: 91

you would need to store it somehow E.G

$.fn.sample = function(){ 
  $parent = $(this);
  console.log($(this).width()); 
  $('#other').hover(function(){
    //Here, $(this) will refer to #other
    // use $parent in here. 
  });
}

Upvotes: 1

mVChr
mVChr

Reputation: 50177

Cache this to $this:

$.fn.sample = function(){
  var $this = $(this);
  console.log($this.width()); 
  $('#other').hover(function(){
    // Here, $(this) will refer to #other
    // and $this will refer to the selector that called sample()
  });
}

Upvotes: 2

Radu
Radu

Reputation: 8699

Easiest way is to save a reference:

$.fn.sample = function(){ 
  console.log($(this).width());
  var $that = $(this)
  $('#other').hover(function(){
    // Here, $(this) will refer to #other
    // but $that will still be the same as above!
  });
}

Upvotes: 2

asawyer
asawyer

Reputation: 17808

You would want to write the original reference to thisas a closure to the inner function like this:

$.fn.sample = function(){ 
  var $parent = $(this);
  console.log($parent.width()); 
  $('#other').hover(function(){
    //Here, $(this) will refer to #other
    $parent.....
  });
}

Upvotes: 3

sod
sod

Reputation: 3928

$.fn.sample = function() {
  var $n = $(this);
  console.log($n.width()); 
  $('#other').hover(function(){
    // use $n
  });
}

Upvotes: 0

Related Questions