View Transitions API 提供了一种机制,可以在更新 DOM 内容的同时,轻松地创建不同 DOM 状态之间的动画过渡。同时还可以在单个步骤中更新 DOM 内容。
概念和用法
视图过渡是一种流行的设计选择,可以减少用户认知负荷,帮助他们保持上下文,并减少他们在应用程序的状态或视图之间移动时感知的加载延迟。
但是,在 Web 上创建视图过渡历来很困难。在单页应用程序(SPA)中,状态之间的过渡往往需要编写大量的 CSS 和 JavaScript 来:
1.处理新旧内容的加载和定位。2.为新旧状态添加动画以创建过渡。3.防止用户与旧内容的意外交互而导致的问题。4.完成过渡后删除旧内容。
像阅读位置丢失、焦点混乱和实时区域宣告的奇怪行为等无障碍问题,也可能由于新旧内容同时存在于 DOM 中而导致。此外,跨文档视图过渡(即在常规非 SPA 网站中跨越不同页面)是不可能的。
View Transitions API 提供了一种更简单的方法来处理必需的 DOM 更改和过渡动画。
创建基本视图过渡
这段代码足以处理显示的图像之间的过渡。支持的浏览器将以平滑的交叉淡入淡出(默认的视图过渡)显示新旧图像和标题的变化。它仍可以在不支持的浏览器中工作,但没有漂亮的动画效果。
<body>
<ul id="container">
<li>https://img0.baidu.com/it/u=1954288067,809682030&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889</li>
<li>https://img0.baidu.com/it/u=2773829836,1252285754&fm=253&fmt=auto&app=138&f=PNG?w=500&h=500</li>
</ul>
<div>
<img id="galleryImg" src="https://img0.baidu.com/it/u=1954288067,809682030&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889" alt="">
</div>
<script>
const container = document.getElementById('container');
const galleryImg = document.getElementById('galleryImg');
container.onclick = function(e) {
updateView(e.target.innerHTML)
}
function updateView(src) {
const displayNewImage = () => {
galleryImg.src = src;
};
// 浏览器不支持 View Transitions 时的回退方案:
if (!document.startViewTransition) {
displayNewImage();
return;
}
// 开始一次视图过渡:
const transition = document.startViewTransition(() =>
displayNewImage()
);
}
</script>
</body>
值得一提的是,startViewTransition() 返回一个 ViewTransition 实例,该实例包含了多个 Promise, 允许你在到达视图过渡过程的不同阶段时运行代码。
视图过渡过程
让我们来看看这是如何工作的:
1、 当调用 document.startViewTransition()
时,API 会截取当前页面的屏幕截图。
2、 接下来,调用传递给 startViewTransition() 的回调函数,即 displayNewImage,这会导致 DOM 发生更改。当回调函数成功运行时,ViewTransition.updateCallbackDone
Promise 成功态,允许你响应 DOM 更新。
3、 API 会捕获页面的新状态并实时展示。
4、 API 构造了一个具有以下结构的伪元素树:
::view-transition
└─ ::view-transition-group(root)
└─ ::view-transition-image-pair(root)
├─ ::view-transition-old(root)
└─ ::view-transition-new(root)
1.::view-transition
是视图过渡叠加层的根元素,它包含所有视图过渡且位于所有其他页面内容的顶部。2.::view-transition-old
是旧页面视图的屏幕截图,且 ::view-transition-new
是新页面视图的实时展示。这两者都呈现为替换内容,就像 <img>
或 <video>
那样,这意味着它们可以方便的使用属性进行样式设置,例如 object-fit 和 object-position。
当过渡动画即将运行时,ViewTransition.ready
Promise 成功态,你可以响应它进行一些操作,例如运行自定义的 JavaScript 动画,而不是默认的动画。
5、 旧页面视图的 opacity 从 1 过渡到 0,而新视图从 0 过渡到 1,这就是默认的交叉淡入淡出效果。
6、 当过渡动画结束时,ViewTransition.finished
Promise 成功态,你可以响应它进行一些操作。