适用于多页面应用的跨文档视图过渡

当两个不同的文档之间发生视图过渡时,称为跨文档视图过渡。多页应用 (MPA) 通常就是这种情况。从 Chrome 126 开始,Chrome 支持跨文档视图过渡。

Browser Support

  • Chrome: 126.
  • Edge: 126.
  • Firefox: not supported.
  • Safari: 18.2.

Source

跨文档视图过渡所依赖的构建块和原则与同文档视图过渡完全相同,这是有意为之:

  1. 浏览器会拍摄新旧页面上具有唯一 view-transition-name 的元素的快照。
  2. 在渲染被抑制时,DOM 会更新。
  3. 最后,过渡效果由 CSS 动画提供支持。

与同文档视图过渡相比,跨文档视图过渡的不同之处在于,您无需调用 document.startViewTransition 即可开始视图过渡。相反,跨文档视图过渡的触发因素是从一个网页到另一个网页的同源导航,这种操作通常由网站用户点击链接来执行。

换句话说,没有可调用的 API 来启动两个文档之间的视图过渡。不过,需要满足以下两个条件:

  • 两个文档都需要位于同一来源。
  • 两个网页都需要选择启用,才能允许视图过渡。

本文档后面部分将介绍这两种情况。


跨文档视图过渡仅限于同源导航

跨文档视图过渡仅限于同源导航。如果参与导航的两个网页的来源相同,则该导航被视为同源导航。

网页的来源是所用架构、主机名和端口的组合,如 web.dev 上所述

突出显示了架构、主机名和端口的网址示例。它们共同构成了来源。
突出显示了架构、主机名和端口的示例网址。它们共同构成来源。

例如,当从 developer.chrome.com 导航到 developer.chrome.com/blog 时,您可以进行跨文档视图过渡,因为它们是同源的。 从 developer.chrome.com 导航到 www.chrome.com 时,您无法进行该过渡,因为它们是跨源和同站点的。


跨文档视图过渡是选择启用的功能

如需在两个文档之间实现跨文档视图过渡,参与过渡的两个页面都需要选择启用此功能。这是通过 CSS 中的 @view-transition at 规则实现的。

@view-transition at-rule 中,将 navigation 描述符设置为 auto,以针对跨文档、同源导航启用视图转换。

@view-transition {
  navigation: auto;
}

通过将 navigation 描述符设置为 auto,您可以选择允许以下 NavigationType 发生视图转换:

  • traverse
  • pushreplace,前提是激活不是由用户通过浏览器界面机制发起的。

auto 中排除的导航包括:使用网址地址栏或点击书签进行的导航,以及任何形式的用户或脚本发起的重新加载。

如果导航时间过长(在 Chrome 中超过 4 秒),则会跳过视图过渡,并显示 TimeoutError DOMException

跨文档视图过渡演示

请查看以下演示,该演示使用视图转换创建了堆栈导航器演示。此处没有对 document.startViewTransition() 的调用,视图转换是通过从一个页面导航到另一个页面来触发的。

Stack Navigator 演示的录制视频。需要 Chrome 126 及更高版本。

自定义跨文档视图过渡

如需自定义跨文档视图过渡效果,您可以使用一些 Web 平台功能。

这些功能本身不属于视图过渡 API 规范,但旨在与该规范搭配使用。

pageswappagereveal活动

Browser Support

  • Chrome: 124.
  • Edge: 124.
  • Firefox: not supported.
  • Safari: 18.2.

Source

为了让您能够自定义跨文档视图过渡效果,HTML 规范新增了两个可供您使用的事件:pageswappagereveal

无论是否即将发生视图过渡,这两个事件都会在每次同源跨文档导航时触发。如果两个页面之间即将发生视图过渡,您可以使用这些事件的 viewTransition 属性访问 ViewTransition 对象。

  • pageswap 事件在网页的最后一个帧渲染之前触发。您可以使用此功能在拍摄旧快照之前对即将退出的网页进行一些临时更改。
  • pagereveal 事件会在网页初始化或重新激活后,但在首次渲染机会之前触发。借助此功能,您可以在拍摄新快照之前自定义新页面。

例如,您可以利用这些事件通过写入和读取 sessionStorage 中的数据来快速设置或更改某些 view-transition-name 值,或者将数据从一个文档传递到另一个文档,从而在视图过渡实际运行之前自定义视图过渡。

let lastClickX, lastClickY;
document.addEventListener('click', (event) => {