
在 firefox 中,为新插入 dom 的元素添加 css transition 时,单纯依赖 `settimeout` 或 `requestanimationframe` 往往无法稳定触发动画;使用 web animations api 的 `element.animate()` 方法可绕过渲染时机问题,实现可靠、零延迟、跨浏览器兼容的过渡效果。
当动态创建并插入一个元素(如
根本原因在于:CSS transitions 仅在属性值发生“变化”且该变化跨越了样式计算与布局/绘制阶段时才会启动。若元素插入后立即应用 .show 类,浏览器可能在单次样式刷新中直接将 opacity: 0 → 1 视为初始状态,跳过过渡。
✅ 推荐解法:使用原生 Web Animations API
element.animate() 显式声明关键帧和持续时间,不依赖 CSS 类切换或样式重计算时机,而是由浏览器动画引擎独立调度,确保在所有现代浏览器(Chrome、Firefox、Safari、Edge ≥79)中一致生效:
const div = document.createElement('div');
div.textContent = 'Hello, animated!';
document.body.appendChild(div);
// 立即启动 opacity 淡入动画(200ms)
div.animate(
[{ opacity: 0 }, { opacity: 1 }],
{ duration: 200, easing: 'ease-out' }
);? 补充技巧:
立即学习“前端免费学习笔记(深入)”;
- 若需配合 CSS 其他样式(如 transform, height),同样适用,例如:
div.animate( [{ opacity: 0, transform: 'scale(0.95)' }, { opacity: 1, transform: 'scale(1)' }], { duration: 250 } ); - 动画完成后可附加逻辑(如清理、回调):
const animation = div.animate([...], { duration: 200 }); animation.onfinish = () => console.log('Fade-in completed!');
⚠️ 注意事项:
- 不支持 IE(但 IE 已停止支持,无需降级);如需兼容旧环境,可结合 web-animations-js polyfill;
- 避免在 animate() 后再通过 CSS 类覆盖动画属性(会中断动画),应统一用 JS 控制或使用 animation-fill-mode: forwards 配合 CSS 动画;
- 性能上,animate() 使用合成器线程,比强制同步布局(如 offsetHeight 触发)更高效、更可靠。
综上,放弃“加类 + 延迟”这种脆弱模式,拥抱 element.animate() —— 它是现代 Web 动画的标准化、声明式、高可靠性方案。










