mpa页面跳转时transition失效的根本原因是整页卸载导致dom瞬间销毁,transition缺乏执行前提;唯一开箱即用解法是chrome111+等支持的view transitions api,通过浏览器自动截取新旧快照实现过渡。

MPA 页面跳转时 transition 失效的根本原因
直接给 body 或 html 加 transition: opacity 0.3s,再用 window.location.href 跳转,动画必然不执行——不是写法错,是浏览器行为决定的。
页面跳转触发整页卸载,DOM 瞬间销毁,所有 CSS 类、内联样式、JS 监听器全部清空。transition 连“开始”都来不及注册,更别说完成。
- 浏览器不会保留旧页面的渲染上下文,
display/visibility切换在跨页场景下完全无意义 -
opacity动画必须作用在“存活”的元素上;而跳转瞬间,整个 document 就被替换了 - 试图用
beforeunload拦截并加类?该事件不允许异步操作,且现代浏览器已限制其执行时长
View Transitions API 是唯一真正开箱即用的解法
Chrome 111+、Edge 111+、Safari 17.4+ 已原生支持 document.startViewTransition(),它不依赖 DOM 共存,而是由浏览器自动截取快照、合成过渡帧。
对 MPA(每个 URL 对应独立 HTML 文件)也有效,前提是:新旧页面结构兼容(如都有 #content),且跳转发生在同源下。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 只需包裹 DOM 更新逻辑:
document.startViewTransition(() => { /* 替换 content 内容 */ }); - 动画控制全靠 CSS 伪元素:
::view-transition-old(root)和::view-transition-new(root) - 禁用 JS 框架也能工作,但需确保 history.pushState() 与内容替换在同一个回调里
手动实现 MPA 过渡时最容易漏掉的三件事
若因兼容性必须手写壳页方案(fetch + innerHTML 替换),以下三点常被跳过,导致动画卡顿或闪屏:
- 没调用
void element.offsetWidth强制重排:新内容插入后立即加动画 class,但浏览器可能合并重排,导致动画不触发 - 没清理
will-change:Safari 下加了will-change: transform, opacity却不及时移除,会持续占用 GPU 内存,后续动画变慢 - 没处理
backface-visibility: hidden:iOS Safari ≤16 对 transform 合成层优化差,不加此声明容易掉帧
过渡动画中 filter / box-shadow 的隐性代价
哪怕只给动效容器加一行 filter: blur(1px) 或 box-shadow: 0 2px 8px rgba(0,0,0,0.1),都可能让浏览器放弃硬件加速,退回到 CPU 渲染。
这在低端 Android 或旧 iPad 上尤为明显:动画从 60fps 掉到 20fps,首帧延迟超过 200ms。
- 动效区域尽量避免
filter、box-shadow、大尺寸background-image - 若必须用,改用
transform: translateZ(0)或will-change: transform(仅动画前 1 帧设置)强制图层提升 - 用 Chrome DevTools 的 Rendering 面板勾选 “Paint flashing”,能直观看到哪些区域在频繁重绘
真实项目里,最常被低估的是结构一致性——新旧页面的 #content 内部 DOM 层级、class 命名、甚至 script 加载顺序稍有差异,就可能导致 ::view-transition-old 匹配失败,回退成硬切。这不是代码写得不够多,而是 HTML 本身成了接口契约。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










