你可能已经习惯了用 setTimeout 来延迟执行某段代码,但在jQuery的动画世界里,还有一个更“内行”的做法,那就是 delay()。它俩虽然都能实现等待,但运行机制不同。
setTimeout 是JavaScript原生的全局定时器,它会中断当前执行流,在指定时间后将函数推入事件循环。而 delay() 是jQuery为动画队列设计的,它只在队列中占据一个“等待位”,不会阻断其他代码的运行,也不会让UI线程卡死。简单说,如果你是在连续调用一系列jQuery动画效果(比如淡入后滑出、再展开),想让它们之间有节奏地依次登场,delay() 是你应该优先考虑的工具。
语法:两个参数,一个核心用途
$(selector).delay(speed, queueName);
-
speed:延迟时长。可以是
"slow"(600ms)、"fast"(200ms) 或者直接写毫秒数,比如1500表示等1.5秒。我个人在做多元素依次入场的效果时,喜欢用200到400毫秒的间隔,这个节奏看起来干脆利落,不会有拖沓感。 -
queueName:队列名称,可选参数。绝大多数时候你不需要碰它,默认值是
"fx",也就是jQuery标准效果队列。除非你在同时操作多个自定义队列,否则这一项可以安心忽略。
示例一:delay() 的基础用法
先来看一个简单的例子。点击按钮后,一个黑色方块不会立即出现,而是先等待一个“慢速”时长,再执行淡入。
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
// 先延迟"slow"时长,再执行fadeIn
$("#box1").delay("slow").fadeIn();
});
});
</script>
</head>
<body>
<button>点击显示方块</button><br>
<div id="box1" style="width:90px;height:90px;display:none;background-color:black;"></div><br>
</body>
</html>
这里 delay("slow") 做的事,就是在动画队列里插入一个600毫秒的空等待,之后才轮到 fadeIn() 执行。如果你把 delay 去掉,按钮一按,方块会立刻开始淡入,少了一层“蓄势”的仪式感。
示例二:不同延迟值,制造节奏序列
delay() 真正的价值体现在多个元素依次动画的场景。下面的代码展示了五个彩色方块,点击同一个按钮后,它们因为各自设置了不同的 delay 时间,会错落有致地逐一显现。
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$("#box1").delay("fast").fadeIn(); // 约200ms后开始淡入
$("#box2").delay("slow").fadeIn(); // 约600ms后开始淡入
$("#box3").delay(1000).fadeIn(); // 正好1000ms后开始淡入
$("#box4").delay(2000).fadeIn(); // 2000ms后开始淡入
$("#box5").delay(4000).fadeIn(); // 4000ms后开始淡入
});
});
</script>
</head>
<body>
<p>点击按钮,观察五个方块以不同的延迟时间依次淡入。</p>
<button>依次显示方块</button>
<br><br>
<div id="box1" style="width:90px;height:90px;display:none;background-color:black;"></div><br>
<div id="box2" style="width:90px;height:90px;display:none;background-color:green;"></div><br>
<div id="box3" style="width:90px;height:90px;display:none;background-color:blue;"></div><br>
<div id="box4" style="width:90px;height:90px;display:none;background-color:red;"></div><br>
<div id="box5" style="width:90px;height:90px;display:none;background-color:purple;"></div><br>
</body>
</html>
这里有一个细节值得注意:五个 delay().fadeIn() 链式调用是几乎同时被触发的,但它们各自在队列里排了不同长度的队。最终呈现出来的,就是一种像钢琴键被从低到高依次按下的视觉节奏。这种效果用 setTimeout 当然也能实现,但代码会分散在不同地方,可读性和维护性远不如 delay() 这样把动画指令一条条串在同一行来得直观。
什么时候用 delay(),什么时候用 setTimeout?
这是我经常被问到的问题,分享一个个人判断标准:
-
用
delay():当你要控制的是jQuery效果队列内部的执行节奏。典型场景是,同一个元素或一组元素上的动画需要“一步接一步,中间停一下”。比如先让一个面板slideDown,等半秒后自动fadeOut。这时候用.slideDown().delay(500).fadeOut()一行就写清楚了。 -
用
setTimeout:当你要延迟执行的是与动画队列无关的操作。比如延迟发起一次AJAX请求、延迟修改某个非CSS属性、延迟执行一个独立的函数。delay()管不到这些东西,它只认jQuery的fx队列。
另外提醒一点:delay() 只能延迟队列中后续的方法。如果你想让一个已经开始的动画中途暂停,delay() 做不到,那是 stop() 的地盘。这个边界要分清楚。
本节课程知识要点
-
队列专属延迟:
delay()是jQuery动画队列的专用等待方法,不能替代setTimeout用于通用逻辑延迟。 -
默认队列名:不写
queueName参数时,作用于默认的"fx"标准效果队列,覆盖绝大多数使用场景。 -
链式编排:
delay()返回的仍然是jQuery对象,因此可以无缝串接fadeIn、slideUp等其他动画方法,形成流畅的链式动画编排。 -
适用边界:仅对jQuery效果方法(如
animate、fadeOut等)有效。对非效果方法(如addClass、css)如需延迟效果,应将其放在回调函数中,或使用queue()方法手动入队。 -
节奏利器:利用不同元素设置不同的
delay值,可以轻松创造出错落有致的序列动画,是构建列表项依次入场、散落展示等视觉节奏的核心技巧。