CSS动画配合JS控制的核心是通过classList操作动画类,定义独立动画类并用forwards保持末帧,暂停需用animation-play-state,监听animationend事件衔接逻辑,支持data属性与CSS变量动态调控。
用 CSS 动画配合 JS 控制动画状态,核心是通过 JS 操作元素的 class(比如添加、移除或切换),让 CSS 中预定义的动画类生效或暂停。这种方式解耦清晰、性能好,且易于维护。
先在 CSS 中写好动画关键帧和对应的触发类,不要直接用 animation 写在基础样式里,而是放在一个独立的 class 中,比如 .animate-slide:
@keyframes slideIn {
from { opacity: 0; transform: translateX(-20px); }
to { opacity: 1; transform: translateX(0); }
}
.animate-slide {
animation: slideIn 0.3s ease-out forwards;
}
注意加 forwards

推荐使用 element.classList 的方法,语义明确、兼容性好:
el.classList.add('animate-slide')
@keyframes 动画,但可通过临时设 animation-play-state: paused 实现。建议定义一个暂停类:.animate-paused { animation-play-state: paused !important; }el.classList.add('animate-paused')
offsetHeight),最后重新添加——触发重播:el.classList.remove('animate-slide');
void el.offsetHeight;
el.classList.add('animate-slide');CSS 动画有原生事件 animationend,JS 可监听它来清理状态或衔接下一步逻辑:
el.addEventListener('animationend', () => {
console.log('动画结束');
el.classList.remove('animate-slide');
});
注意:该事件在动画被取消(如 class 被提前移除)时不会触发,如有强依赖,建议配合标志位或 Promise 封装。
想动态控制动画时长、延迟或贝塞尔曲线?可以结合 data- 属性和 CSS 自定义属性:
#box {
--anim-duration: var(--duration, 0.3s);
animation-duration: var(--anim-duration);
}
#box.animate-bounce {
animation: bounce var(--anim-duration) ease-in-out;
}
JS 中更新:el.dataset.duration = '0.7s';,CSS 会自动响应(需确保 :root 或父级已声明变量)。