GreenDude
GreenDude

Reputation: 567

setTimeout inside $.each()

ok, so I've got this code:

$(this).find('article.loading').each( function(i) {

    var el = this;
        setTimeout(function () {
        $(el).replaceWith($('#dumpster article:first'));
    }, speed);

});

I want to replace each element with another but I want a delay between each replace.

I can't figure out why this isn't working, it just replaces all of them after one timeout.

Any ideas?

Thanks.

Upvotes: 14

Views: 24656

Answers (4)

haudoing
haudoing

Reputation: 613

I just modify your code and make a little change. Just a little trick.

$(this).find('article.loading').each( function(k, v) {
    var el = this;
        setTimeout(function () {
        $(el).replaceWith($('#dumpster article:first'));
    }, k*speed);
});

P.S. This solution is not the optimize solution but it help you to get job done fast. In most case it's fine. Just like jquery itself.

Upvotes: 22

RaYell
RaYell

Reputation: 70414

It's exactly how Andy McCluggage written. I think something like this could help you.

var speed = 1000;

// init timer and stores it's identifier so it can be unset later
var timer = setInterval(replaceArticle, speed);

var articles =  $('article.loading');
var length = articles.length;

var index = 0;
function replaceArticle() {
     articles.eq(index).replaceWith($('#dumpster article:first'));

     index++;

     // remove timer after interating through all articles
     if (index >= length) {
         clearInterval(timer);
     }
}

Upvotes: 17

Andy McCluggage
Andy McCluggage

Reputation: 38698

You are looping through the elements and adding a timer to each with the same configuration. Essentially a new timer is instantly set up for each element. On the first tick of all the timers the elements are updated. The interval is the same for each so they all appear to update at the same time.

Your logic needs to be centred around the timer. Each tick of the timer needs to update the next element in the collection. You don't need an each loop, use the timer combined with an incremented index as your looping mechanism, stopping the timer once you have updated the last element.

var elements = $(this).find('article.loading');
var index = 0;

setTimeout(function () {
    $(elements).get(index).replaceWith($('#dumpster article:first'));
    index++;
}, speed);

Something like above, but remember to also stop the timer!

Upvotes: 18

Ionuț Staicu
Ionuț Staicu

Reputation: 22156

Try with window.setTimeout.

Upvotes: -1

Related Questions