Konrad Viltersten
Konrad Viltersten

Reputation: 39220

Unexpected scope for $(this) in jQuery using each and function

When i execute the following code, i'd expect the same element id to be alerted twice but instead, the first one is correct while the second always show the name of the first element in the set.

$("div.someClass").each(function (index) {
  $(this).click(function () {
    alert($(this).attr("id")); // Here i get the actually clicked element
    $.when($("div.someClass").animate({ }, 0)).then(function () {
      alert($(this).attr("id")); // Here i get the first element in of that class
    });
  });
});

Why is it so? How to resolve it? I have tried passing the name of the element into the function but it didn't work.

Upvotes: 2

Views: 1601

Answers (3)

jholloman
jholloman

Reputation: 1979

You need to access the element of the each function: http://api.jquery.com/each/

$("div.someClass").each(function (index, element) {
  $(element).click(function () {
    var $this = $(this);
    alert($this.attr("id")); // Here i get the actually clicked element
    $.when($("div.someClass").animate({ }, 0)).then(function () {
      alert($this.attr("id")); // Here i get the first element in of that class
    });
  });
});

Also helps to read up on what "this" means: https://developer.mozilla.org/en/JavaScript/Reference/Operators/this jQuery can confuse your understanding of what "this" is supposed to be with all the context changing it does for event handling.

Upvotes: 2

Adil
Adil

Reputation: 148150

Save the $(this) in some variable for instance that and later use in animate

$("div.someClass").each(function (index) {
  $(this).click(function () {
    alert($(this).attr("id")); // Here i get the actually clicked element
    var that = $(this);
    $.when($("div.someClass").animate({ }, 0)).then(function () {           
      alert(that.attr("id")); // Here i get the first element in of that class
      alert($(this).attr("id")); 
    });
  });
});

Upvotes: 4

jfriend00
jfriend00

Reputation: 707846

The value of this is automatically altered on every function call. So, unless multiple function calls conspire to purposely preserve a particular value of this by passing it in and then using .apply() or .call() to set it before calling your callback, it will be different. Javascript goes by these rules:

  • If you make a method call, the value of this is set to the object whose method it is.
  • If you make a normal function call, this is set to the global object (normally window).
  • If you use fn.apply() or fn.call(), then this is set based on the first argument.

The simplest solution is to save the value of this in a local variable and then refer to that.

$("div.someClass").each(function (index) {
  var self = $(this);
  self.click(function () {
    alert(self.attr("id")); // Here i get the actually clicked element
    $.when($("div.someClass").animate({ }, 0)).then(function () {
      alert(self.attr("id")); // Here i get the first element in of that class
    });
  });
});

Upvotes: 4

Related Questions