背景与核心价值无刷新页面转场减少认知断裂,提升导航连贯性与沉浸体验。原生 API 提供共享元素命名与过渡状态,无需繁重的手写快照与坐标计算。兼容性与前置条件Chrome/Edge 支持良好;Safari 需最新版本或回退策略;Firefox 正在推进中。与 SPA 路由/Navigation API 搭配效果最佳;支持 SSR 回退为渐隐渐显。基本使用:无刷新路由转场async function navigateWithTransition(render: () => void) {

if ((document as any).startViewTransition) {

const vt = (document as any).startViewTransition(async () => {

await render();

});

await vt.finished;

return { ok: true };

}

render();

return { ok: true, fallback: true };

}

CSS 定义旧/新视图状态::root::view-transition-old(root) { animation: fade-out .18s ease; }

:root::view-transition-new(root) { animation: fade-in .18s ease; }

@keyframes fade-out { from { opacity: 1 } to { opacity: 0.8 } }

@keyframes fade-in { from { opacity: 0.8 } to { opacity: 1 } }

共享元素:命名与对齐<article>

<img src="thumb.jpg" style="view-transition-name: card-image">

<h2 style="view-transition-name: card-title">标题</h2>

</article>

在详情页保持相同名称:<figure>

<img src="large.jpg" style="view-transition-name: card-image">

<figcaption style="view-transition-name: card-title">标题</figcaption>

</figure>

常见规则:为参与过渡的元素指定稳定的尺寸/约束,避免布局跳动。减少参与元素数量,保持关键焦点,避免过度动画导致干扰。路由集成示例function renderRoute(path: string) {

// 根据 path 渲染页面内容(SSR/CSR 均可)

}

async function onLinkClick(path: string) {

await navigateWithTransition(() => renderRoute(path));

}

可访问性与用户偏好尊重 `prefers-reduced-motion`:当用户偏好减少动效时,禁用或弱化动画。@media (prefers-reduced-motion: reduce) {

:root::view-transition-old(root),

:root::view-transition-new(root) { animation: none }

}

焦点管理:确保过渡完成后焦点落在主标题或主要交互控件上。验证指标(Chrome 128/Edge 130)动画帧丢失率(P95):≤ 2%。过渡启动延迟(P95):≤ 32ms。INP 无显著劣化:交互响应保持 ≤ 200ms(P95)。用户偏好尊重度:`prefers-reduced-motion` 命中场景下动画完全禁用(抽检 100%)。回退策略不支持环境:直接渲染新视图或采用 CSS 渐隐;避免 JS 重排引发布局抖动。内容变动较大时:只做根视图淡入淡出,避免共享元素带来的错位。测试清单高密度导航:连续触发 30 次转场无异常与卡顿。共享元素一致性:名称匹配与尺寸约束正确,避免“跳闪”。可访问性:键盘与读屏导航路径正确,焦点定位合理。应用场景文章列表→详情、商品卡片→详情、仪表盘视图切换、图片廊浏览。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部