setTimeout внутри $.each()
Хорошо, у меня есть этот код:
$(this).find('article.loading').each( function(i) {
var el = this;
setTimeout(function () {
$(el).replaceWith($('#dumpster article:first'));
}, speed);
});
Я хочу заменить каждый элемент другим, но я хочу задержку между каждой заменой.
Я не могу понять, почему это не работает, оно просто заменяет их все после одного таймаута.
Есть идеи?
Благодарю.
4 ответа
Вы перебираете элементы и добавляете таймер к каждому с одинаковой конфигурацией. По сути, новый таймер мгновенно устанавливается для каждого элемента. На первом тике всех таймеров элементы обновляются. Интервал одинаков для каждого, поэтому все они обновляются одновременно.
Ваша логика должна быть сосредоточена вокруг таймера. Каждый тик таймера должен обновлять следующий элемент в коллекции. Вам не нужен каждый цикл, используйте таймер в сочетании с инкрементным индексом в качестве механизма зацикливания, останавливая таймер после обновления последнего элемента.
var elements = $(this).find('article.loading');
var index = 0;
setTimeout(function () {
$(elements).get(index).replaceWith($('#dumpster article:first'));
index++;
}, speed);
Нечто подобное выше, но не забудьте также остановить таймер!
Я просто изменяю ваш код и делаю небольшие изменения. Просто маленький трюк.
$(this).find('article.loading').each( function(k, v) {
var el = this;
setTimeout(function () {
$(el).replaceWith($('#dumpster article:first'));
}, k*speed);
});
Это именно то, как написал Энди МакКлагжаг. Я думаю, что-то подобное может помочь вам.
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);
}
}