一、纯 CSS 方案(利用 animationend 事件)
通过监听动画结束事件 animationend,触发下一个动画。
<div class="box" id="box1">动画1</div>
<div class="box" id="box2">动画2</div>
.box {
width: 100px;
height: 100px;
opacity: 0;
}
/* 初始隐藏 */
#box1 { background: red; }
#box2 { background: blue; }
/* 动画定义 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
const box1 = document.getElementById('box1');
const box2 = document.getElementById('box2');
// 监听第一个动画结束
box1.addEventListener('animationend', () => {
box2.style.animation = 'fadeIn 1s forwards'; // 触发第二个动画
});
// 启动第一个动画
box1.style.animation = 'fadeIn 1s forwards';
二、Web Animations API(现代浏览器)
利用 finished Promise 控制动画队列。
const box1 = document.getElementById('box1');
const box2 = document.getElementById('box2');
// 定义动画
const animate1 = box1.animate(
[{ opacity: 0 }, { opacity: 1 }],
{ duration: 1000 }
);
// 第一个动画完成后触发第二个
animate1.finished.then(() => {
box2.animate(
[{ opacity: 0 }, { opacity: 1 }],
{ duration: 1000 }
);
});
三、CSS Transition + Promise(精确控制)
将 CSS 过渡包装成 Promise。
function waitForTransition(element) {
return new Promise(resolve => {
element.addEventListener('transitionend', resolve, { once: true });
});
}
// 使用示例
const box = document.querySelector('.box');
// 第一个动画
box.style.transform = 'translateX(200px)';
box.style.transition = 'transform 1s';
waitForTransition(box).then(() => {
// 第二个动画
box.style.transform = 'translateY(200px)';
});
四、Async/Await 链式调用
用现代 JavaScript 语法组织动画队列。
async function runAnimations() {
const box1 = document.getElementById('box1');
const box2 = document.getElementById('box2');
// 第一个动画
await box1.animate([{ opacity: 0 }, { opacity: 1 }], 1000).finished;
// 第二个动画
await box2.animate([{ opacity: 0 }, { opacity: 1 }], 1000).finished;
// 更多动画...
}
runAnimations();
五、GSAP 动画库(专业级解决方案)
使用业界标杆动画库 GSAP 的时序控制。
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>
// 创建时间线
const tl = gsap.timeline();
// 链式调用动画
tl.to("#box1", { duration: 1, x: 200 })
.to("#box2", { duration: 1, y: 200 }, "+=0.5"); // 延迟 0.5 秒执行

image.png
最佳实践
简单动画序列 → 纯 CSS + animationend 事件
现代浏览器项目 → Web Animations API + async/await
企业级复杂动画 → GSAP 时间线控制
关键点:避免使用 setTimeout 控制动画时序(帧率不稳定),优先使用基于事件或 Promise 的方案。
