view transitions api仅对单页内同步dom更新生效,直接a href跳转或location.href会卸载文档导致快照失败;必须用document.startviewtransition()包裹同步操作,且view-transition-name须成对、稳定、大小写敏感并确保元素已挂载。

document.startViewTransition() 必须包裹同步 DOM 更新,不能用于 location.href 或 a href 跳转——它只对单页应用内同一文档的 DOM 变更生效。
为什么直接跳转页面没动画?
点击 <a href="/next"></a> 或执行 location.href = "/next" 会卸载当前 HTML 文档、加载新文档,document.startViewTransition() 在旧文档中调用后,新文档里根本不存在过渡上下文。浏览器连“旧快照”都拍不到,自然没动画。
在 SPA 中正确触发过渡的写法
过渡必须包裹**已知、同步、可预测的 DOM 更新操作**,比如替换容器内容、切换 class、重渲染组件根节点。
- ✅ 正确:
document.startViewTransition(() => { main.innerHTML = newHTML; }) - ❌ 错误:
document.startViewTransition(() => { router.push('/detail'); })—— 这没改 DOM,只是发导航指令 - ⚠️ 避免异步:
await fetch(...)或setTimeout放在回调里会导致快照提前结束,动画中断 - Vue/React 用户注意:确保 DOM 已挂载且渲染完成,可用
nextTick或flushSync包裹更新逻辑
view-transition-name 配对失败的常见原因
命名过渡靠字符串精确匹配,90% 的“没动画”问题出在这里。
- 旧元素和新元素都必须有
style="view-transition-name: hero",大小写、空格、引号全要一致 - 不能动态生成值:
view-transition-name: item-${id}但前后id不同 → 匹配失败 - 元素必须已挂载到
document才能被拍快照;刚createElement没append的节点不会参与过渡 - 避免给无关元素加该属性,否则它们会被卷入过渡,干扰图层顺序和动画节奏
::view-transition-old 和 ::view-transition-new 的样式陷阱
浏览器把旧/新视图分别渲染为独立合成层,但很多 CSS 会让旧元素“不可绘制”,导致快照为空。
- ❌ 禁止在快照前设
display: none、visibility: hidden或opacity: 0 - ✅ 可用
opacity: 0.001占位,或用backdrop-filter+ 半透背景模拟遮罩 - 默认有淡入淡出,自定义时务必统一
animation-duration,否则旧层早消失、新层晚入场,出现空白帧 - 调试时打开 DevTools 的 Layers 面板,确认目标元素进了独立合成层(带“View Transition”标签)
view-transition-name 是否稳定成对、旧元素是否始终处于可绘制状态——这三点漏掉任何一环,动画就静默失效。大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











