移动端息屏后CSS3动画停止是浏览器主动冻结渲染管线所致,非bug;需用class切换+强制reflow实现可靠重播,避免依赖visibilitychange事件及animation-play-state。

移动端息屏后 CSS3 动画停止是浏览器主动冻结渲染管线的结果,不是 bug,也无法靠 animation-play-state 恢复播放——它只会从冻结时刻继续,而非重播。
visibilitychange 事件在移动端的实际触发时机不可靠
Android Chrome 和 iOS Safari(尤其微信 WebView)对 visibilitychange 的响应存在明显延迟或丢失:息屏时可能不触发,亮屏后也可能滞后 200–500ms 才触发。直接在回调里设 element.style.animationPlayState = 'running' 基本无效,因为此时动画时间轴已偏移,且元素可能尚未完成 layout。
- iOS Safari 微信内置浏览器常把
document.visibilityState错报为'visible',哪怕屏幕已黑 - 部分 Android Webview 在息屏瞬间会丢弃
visibilitychange事件,需 fallback 到pagehide/pageshow - 不要依赖单次事件:建议同时监听
visibilitychange、pagehide、focus三个事件,任一触发都尝试重置
用 class 切换强制重播比操作 animationPlayState 更可靠
修改 style.animationPlayState 只改变播放状态,不重置动画计时器,也不清空已应用的 transform 或 opacity 内联样式。真正重播必须让浏览器“认为这是一个新动画”。
- 先移除动画类:
el.classList.remove('animate-slide') - 强制同步 reflow:
el.offsetHeight或getComputedStyle(el).opacity - 再添加动画类:
el.classList.add('animate-slide') - 动画类中只含
animation声明和animation-fill-mode: none(避免forwards干扰重播)
iOS Safari 下 transform 冲突会导致重播失败
如果元素已有内联 style.transform(比如 JS 动态设置过位移),再通过 CSS 类触发带 transform 的动画,两者会叠加或覆盖,造成动画跳帧甚至不触发。这不是 visibility 问题,而是样式层叠冲突。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
立即学习“前端免费学习笔记(深入)”;
- 统一用 CSS 类管理所有
transform状态,避免 JS 直接写el.style.transform - 重播前可临时清除:
el.style.transform = '',但需确保不影响布局逻辑 - 对关键动画,加
transform: translateZ(0)启用硬件加速,减少 iOS 渲染卡顿
animation-duration 过短在低端 Android 上会被跳过
实测发现,当 animation-duration 小于 0.15s(即 150ms)时,部分 Android 8–10 Webview 会直接忽略首帧,表现为“没动就结束了”。这不是 visibility 问题,而是渲染引擎的最小帧判定阈值。
- 最低设为
0.15s,不要用100ms或更小值 - 若需快速闪现效果,改用
opacity+transition配合setTimeout控制,比@keyframes更稳 - 避免在
@keyframes中混用transform和top/left,前者硬件加速,后者强制重排,混合使用易在息屏唤醒后失步
真正难处理的不是“怎么重播”,而是“怎么判断该不该重播”——有些动画本就不该重播(比如 loading 进度条),有些则必须精确到帧(比如轮播图位置)。别默认所有动画都走同一套 visibility 处理逻辑,按用途分类才是关键。

















