SetTimeout внутри $.each()

ok, поэтому у меня есть этот код:

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

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

});

Я хочу заменить каждый элемент другим, но мне нужна задержка между каждой заменой.

Я не могу понять, почему это не работает, он просто заменяет все из них после одного тайм-аута.

Любые идеи?

Спасибо.

Ответы

Ответ 1

Вы перебираете элементы и добавляете таймер к каждой с той же конфигурацией. По сути, для каждого элемента мгновенно устанавливается новый таймер. При первом тике всех таймеров элементы обновляются. Интервал одинаковый для каждого, поэтому все они обновляются одновременно.

Ваша логика должна быть сосредоточена вокруг таймера. Каждому тику таймера необходимо обновить следующий элемент в коллекции. Вы не нуждаетесь в каждом цикле, используйте таймер в сочетании с инкрементированным индексом в качестве механизма цикла, останавливая таймер после того, как вы обновили последний элемент.

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

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

Что-то вроде выше, но не забудьте также остановить таймер!

Ответ 2

Я просто изменяю ваш код и делаю небольшое изменение. Просто небольшой трюк.

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

Ответ 3

Это точно, как писал Энди Макклауз. Я думаю, что что-то подобное может вам помочь.

var speed = 1000;

// init timer and stores it 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);
     }
}

Ответ 4

Попробуйте с window.setTimeout.