Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout not working with jquery.each, this

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);
});
}
like image 245
valen Avatar asked May 16 '12 08:05

valen


People also ask

Why setTimeout is not working in jquery?

You're passing in a code block to setTimeout() . The problem is that update() is not within scope when executed like that. It however if you pass in a function pointer instead so this works: (function() { $(document).

Is there a limit for setTimeout?

Maximum delay value Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed integer internally. This causes an integer overflow when using delays larger than 2,147,483,647 ms (about 24.8 days), resulting in the timeout being executed immediately.

Does setTimeout run in a different thread?

Sure enough, clicking the button causes the browser to hang. This tells me that setTimeout() does not run on a separate thread.

Is setTimeout thread blocking?

Explanation: setTimeout() is non-blocking which means it will run when the statements outside of it have executed and then after one second it will execute.


1 Answers

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/

like image 143
Richard Dalton Avatar answered Oct 06 '22 00:10

Richard Dalton