滚动时如何实现元素逐个淡入的动画效果?
我在做页面滚动动画,想让多个卡片在滚到视口时逐个淡入,但目前所有元素一进视口就同时触发了。
我用的是 IntersectionObserver,代码大概是这样:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('fade-in');
}
});
});
document.querySelectorAll('.card').forEach(card => {
observer.observe(card);
});
但这样所有 .card 一进入视口就一起加类名,怎么让它们一个一个按顺序淡入?是不是要加延迟?
每个卡片延迟 0.1 秒,第二个 0.2 秒,以此类推。这样进入视口时会一个接一个淡入。
如果想控制速度,改 transitionDelay 的乘数就行。比如
index * 0.15就慢一点。另外提一下,threshold: 0.1 表示元素露出 10% 就触发,比默认的 0 体验好一点,不会太迟钝。
有两种常见做法,都很简单。
第一种是纯 CSS 方案,最省事。在写样式的时候,给每个卡片按顺序加上
transition-delay:这样你的 JS 代码完全不用改,CSS 会自动处理错开时间的问题。缺点是如果卡片数量不固定,得写很多 nth-child,或者用 CSS 变量配合 JS 设置。
第二种是用 JS 动态设置延迟,更灵活:
这样每个卡片的动画会依次延迟 0.1 秒触发,形成逐个淡入的效果。延迟时间可以根据你想要的节奏调整,一般 0.1s 到 0.15s 比较自然。
两种方案都能跑,看你项目情况选一个就行。