View Transitions API 无 updateDOM 回调;DOM 更新须在 startViewTransition 同步执行,异步操作会导致快照捕获失败;可用 finished Promise 或 transitionend 事件监听动画结束。

View Transitions 的 updateDOM 回调根本不存在
HTML View Transitions API 没有名为 updateDOM 的回调。这是常见误解,可能源于对早期提案、Polyfill(如 view-transitions-polyfill)或混淆了 document.startViewTransition() 返回的 ViewTransition 对象的属性。原生 View Transitions(Chrome 111+)只提供 ready、finished 和 skipTransition 等 Promise 属性,不暴露 DOM 更新时机的钩子。
想在动画中更新内容?得靠 document.startViewTransition() 的执行时机
View Transitions 的核心逻辑是:浏览器自动捕获「旧 DOM 快照」→ 启动过渡 → 你同步修改 DOM → 浏览器捕获「新 DOM 快照」→ 淡入/滑动等动画。关键点在于:所有 DOM 更新必须写在 startViewTransition() 的回调函数内部,且是同步执行的。
常见错误是把 DOM 更新放在异步回调(如 setTimeout、fetch().then())里,导致浏览器拍不到新快照,动画卡在旧状态:
document.startViewTransition(() => {
// ✅ 正确:同步更新,浏览器能捕获新 DOM
document.getElementById('title').textContent = 'New Page';
document.getElementById('content').innerHTML = '<p>Loaded</p>';
// ❌ 错误:异步更新,DOM 变更发生在 transition 外部
fetch('/data').then(r => r.json()).then(data => {
document.getElementById('content').textContent = data.text;
});
});
需要异步加载后再过渡?用两层 transition 或手动控制
如果内容依赖网络请求,不能直接在 startViewTransition 回调里同步更新,有两条路:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- 先用一个空/占位 transition 启动动画,再在数据就绪后立即调用第二个
startViewTransition更新真实内容(浏览器会自动衔接) - 禁用自动过渡,用
document.documentElement.style.viewTransitionName = 'none'临时关闭,等数据加载完再显式开启并触发 transition - 更稳妥的做法:在
fetch前就调用startViewTransition,并在回调里先渲染 loading 状态,再用.then()继续更新(只要不脱离 microtask 队列,浏览器仍视为同一 transition 上下文)
真正能监听的只有 transitionend 或 finished Promise
如果你只是想“知道动画什么时候结束”,用 finished:
const vt = document.startViewTransition(() => {
document.body.innerHTML = '<h1>New</h1>';
});
vt.finished.then(() => {
console.log('动画已结束,DOM 已切换完成');
});
注意:finished 解析时,DOM 已是新内容,但此时动画可能还没视觉上完全结束(因含 CSS easing)。若需精确对齐视觉终点,应监听元素上的 transitionend 事件,并确保 transition 属性匹配(如 view-transition-name 对应的 CSS 动画名)。
View Transitions 不提供“DOM 即将更新”或“正在更新中”的钩子——它设计上就是声明式快照对比,不是命令式生命周期控制。想精细干预,就得回到传统 DOM 操作 + CSS 动画组合的老路。


















