user1320260
user1320260

Reputation:

Parsing $(this) to function within setTimeout

I have a function that requires $(this) to be parsed to it. It is located within an each loop. This works as expected. The problem comes when I need to access $(this) when used in conjunction with setTimeout()

DEMO http://jsfiddle.net/6e937r1b/2/

To simplify and demonstrate my issue I have put together a basic fiddle. You will notice that the text is not output.

$("li").each(function(i) {
    /* below example outputs value if i only */
    setTimeout(function() {
        alertThis($(this).text() + i);
    }, 1000 * i);

    /* below example works as you'd expect outputting the text and value of i */
    alertThis($(this).text() + i + ' outside of timeout');
});

function alertThis(text)
{
     alert(text);   
}

Upvotes: 0

Views: 163

Answers (3)

James Montagne
James Montagne

Reputation: 78690

The function passed to each receives a second parameter which is the dom element itself. You can simply use this instead:

$("li").each(function(i, el) {

    setTimeout(function() {
        alertThis($(el).text() + i);
    }, 1000 * i);

    alertThis($(el).text() + i + ' outside of timeout');
});

http://jsfiddle.net/6e937r1b/4/

Upvotes: 0

Joshua Whitley
Joshua Whitley

Reputation: 1186

That's because this loses context within setTimeout(). Put simply, this refers to the global object when inside setTimeout() because you've shifted scope. A typical way to handle this is to store the context of this by storing it in a variable (usually that):

var that = $(this);

Upvotes: 1

tadman
tadman

Reputation: 211670

As always you need to capture this if the scope shifts:

$("li").each(function(i) {
  var target = $(this);

  setTimeout(function() {
    alertThis(target.text() + i);
  }, 1000 * i);

  alertThis(target.text() + i + ' outside of timeout');
});

Upvotes: 3

Related Questions