应优先使用 class 切换控制动画暂停,因其通过 !important 保证优先级、兼容性更好;iOS Safari 等浏览器对 style.animationPlayState 修改响应延迟或失效,且内联样式易被 CSS 规则覆盖。

直接用 animation-play-state 控制暂停,在 iOS Safari、微信内置浏览器、部分 Android Webview 上容易失效——不是你代码写错了,是浏览器对这个属性的 runtime 修改支持不一致。
为什么 class 切换比 style.animationPlayState 更可靠
内联样式(el.style.animationPlayState = 'paused')在某些场景下会被 CSS 规则覆盖,尤其当动画靠 class 触发时;而 class 方案通过 !important 显式压制默认值,优先级可控、可预测。
- iOS Safari 对
style.animationPlayState的修改响应延迟明显,甚至忽略首帧 - 微信内置浏览器(X5 内核)常把 visibilitychange 事件延迟到页面重绘后才触发,此时直接设
running已错过时机 - 多个动画并存时,JS 手动设置需严格按逗号顺序匹配
animation值,稍有错位就部分失效 -
class切换天然支持批量操作(querySelectorAll('.animated').forEach(el => el.classList.toggle('paused'))),无须逐个判断状态
正确写法:CSS 中必须带 !important
很多人漏掉 !important,导致 .paused 类被原始动画规则覆盖。例如:
.animated {
animation: bounce 1s ease-in-out;
}
.paused {
animation-play-state: paused !important;
}
没加 !important 时,Chrome 可能还行,但 Safari 9+ 和 Edge 12+ 会回退到原始 running 状态。
- 不要写成
.paused { animation-play-state: paused; }—— 没用 - 不要指望父类或媒体查询里的
animation-play-state自动生效,它只对已“活跃”的动画起作用 - 如果动画本身用了
animation-fill-mode: forwards,暂停后仍保持终态样式,视觉上不会跳变
后台切回时重播动画必须强制 reflow
仅靠 classList.remove('animate-in'); classList.add('animate-in') 不够,浏览器可能跳过重播。必须插入一次 layout 强制刷新时间轴:
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
el.classList.remove('animate-in');
el.offsetHeight; // 强制 reflow
el.classList.add('animate-in');
}
});
-
el.offsetHeight是最轻量的 reflow 触发方式,比getComputedStyle开销小 - iOS Safari 建议加
setTimeout(() => { ... }, 100),避开刚唤醒时的渲染队列阻塞 - 若动画依赖
transform,确保元素没有内联style.transform,否则 CSS 类中的 transform 会被覆盖,导致重播失败
移动端和低版本兼容的兜底处理
Android 4.4 Webview、Safari ≤ 8 需要前缀,且 getAnimations() 不可用,只能靠 class + reflow 组合拳:
- CSS 中补全前缀:
-webkit-animation-play-state: paused !important; - 避免
animation-duration小于0.15s,否则 Android Webview 可能直接跳过首帧 - 不要在
requestAnimationFrame循环里反复 toggle class,可能引发抖动或丢帧 - 如果动画靠
:hover触发,记得原始状态显式写animation-play-state: running,否则旧版 Safari 不识别 hover 切换
最易被忽略的一点:动画是否“活跃”,取决于它是否已开始播放。刚插入 DOM 的元素,即使加了 .animated 类,也要等下一帧才真正 running——所以 visibilitychange 里操作前,最好确认 getComputedStyle(el).animationPlayState === 'running',否则白忙活。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











