setTimeout not working with jquery.each, this

15,327

Solution 1

Try this:

function reveal_board() {
    $("div").each(function(index) {        
        (function(that, i) { 
            var t = setTimeout(function() { 
                $(that).removeClass("invisible"); 
            }, 500 * i);
        })(this, index);
    });
}

It's generally a bad practice to pass a string to setTimeout() and also I don't think you can pass any variables when using it that way.

I have also wrapped it in a closure to ensure that that always applies to the right element and is not replaced.

Although, like NiftyDude says you might want to pass in the index and use that to display each element in turn.

Working example - http://jsfiddle.net/Cc5sG/

EDIT

Looks like you don't need the closure:

function reveal_board() {
    $("div").each(function(index) {        
        var that = this;
        var t = setTimeout(function() { 
            $(that).removeClass("invisible"); 
        }, 500 * index);        
    });
}

http://jsfiddle.net/Cc5sG/1/

Solution 2

Your this is pointed to the global window.

function reveal_board() {
  $("td").each(function() {
    $this = $(this);
    var t=setTimeout(function(){$this.removeClass("invisible");}, 500);
  });
}

Solution 3

Well, I've had the same problem and I solved it that way... But I have no idea about the performances or whatever, I used it in a very short loop (10 elements max) and it worked perfectly ... By the way I used it to add a class so I'll let you figure out what it gives to remove a class ;).

var elements = $(".elements");
var timeout;

elements.each(function(e){
    timeout = setTimeout(function(index) {
       elements[elements.length-e-1].setAttribute('class', elements[elements.length-e-1].getAttribute('class')+' MY-NEW-CLASS');
    }, 500 * e);
});

Solution 4

First thing first, avoid using string for the first argument of setTimeout, use anon function instead as it's easier to debug and maintain:

$("td").each(function() {
    var $this = $(this);
    var t=setTimeout(function() {
       $this.removeClass("invisible")
    }, 500);
});

Also, I'm not really sure what you are trying to achieve here (update your question later and I'll adapt my answer), but if you want to remove invisible class from each td 500 ms after one another, you can use index:

$("td").each(function() {
    var $this = $(this);
    var t=setTimeout(function(index) {
       $this.removeClass("invisible")
    }, 500 * (index+1));
});
Share:
15,327
valen
Author by

valen

Updated on July 27, 2022

Comments

  • valen
    valen almost 2 years

    I'm trying to add a delay between the jquery .removeClass calls while iterating through the cells of a table. The cells display properly with no setTimeout, but with setTimeout the code breaks. What am I doing wrong?

    function reveal_board() {
    $("td").each(function() {
        var t=setTimeout('$(this).removeClass("invisible")', 500);
    });
    }
    
  • Black
    Black over 6 years
    Sry for the edit, I accidentially downvoted and had to edit so I can upvote again.
  • Satish Ravipati
    Satish Ravipati over 2 years
    how on earth can you write such an elegant way of iterating with setTimeout. I can only give 1 upvote unfortunately