使用以下代码,我希望li元素一个接一个地淡入,但所有元素一起淡入:
$('li').each(function () {
$(this).delay(1000).fadeIn(1000);
});
谁能解释为什么它们不会一个接一个地消失?
.delay
调用不会阻止循环立即进行,因此所有延迟和动画将(几乎)立即开始。
最简单的解决方案是按当前索引号错开延迟:
$('li').each(function(index) {
$(this).delay(1000 * index).fadeIn(1000);
});
更好的解决方案是使用伪递归循环和动画的"完成回调"来触发下一次迭代:
var els = $('li').get();
(function loop() {
if (els.length) {
var el = els.shift();
$(el).fadeIn(1000, loop);
}
})();
此方法通常更可取,因为它确保在前一个动画完成之前不可能开始下一个淡入,并且还避免创建多个并行延迟/淡入队列(每个元素一个),因为第二个动画在第一个动画完成之前不会排队。
这是因为您基本上告诉每个li
等待 1 秒并淡入。所以这就是他们所做的:)
现在,您的代码类似于:
$('li').delay(1000).fadeIn(1000);
尝试这样的事情:
var delay = 0;
$('li').each(function () {
$(this).delay(delay).fadeIn(1000);
delay += 1000;
});
或者,正如Alnitak所建议的那样,一个更干净的方法是使用$.each()
提供的当前索引 :
$('li').each(function (index) {
// index will return the loop index starting to 0
$(this).delay(index*1000).fadeIn(1000);
});
因为each
没有延迟。几乎同时应用每个延迟。
您可能想尝试使用complete
部分 do fadeIn
下一个元素
.fadeIn( [duration ] [, complete ] )
jQuery api doc
对jQuery.each
的误解。这并不意味着要做一个,然后等待它完成然后再继续,为此你需要使用承诺。
相反,请尝试将延迟更改为数组中每个 LI 索引的倍数,例如:
$('li').each(function(index) {
$(this).delay((index + 1) * 1000).fadeIn(1000);
});
由于数组索引总是从 0 开始,并且 0 * 1000 = 0,因此我在乘以 1000 之前将 1 添加到索引中,以确保第一个在 1 秒后发生,第二个在 2 秒后发生,依此类推。
如果您不希望第一个li
淡入 1s 的延迟,那么它很简单:
$('li').each(function(index) {
$(this).delay(index * 1000).fadeIn(1000);
});