使用 View Transitions API 打造無縫的頁面過渡動畫

5 分鐘

1. 頁面跳轉的體驗鴻溝

在 Web 開發中,我們長期面臨一個體驗上的兩難選擇:

  • 多頁應用程式 (MPA): 架構簡單、穩定,但每次頁面跳轉都會有一次完整的載入,帶來「白屏」或「閃爍」,體驗不連貫。
  • 單頁應用程式 (SPA): 透過前端路由實現了流暢的「無重新整理」體驗,但開發者需要手動處理複雜的過渡動畫、狀態管理和程式碼分割,開發成本高昂。

有沒有一種方法,既能保持 MPA 的簡單性,又能獲得 SPA 的流暢過渡體驗?View Transitions API 正是為此而生。

2. View Transitions API 是什麼?

View Transitions API 是一個瀏覽器原生 API,它提供了一種機制,讓我們能夠輕鬆地在兩個不同的 DOM 狀態之間建立動畫過渡。

它的核心工作流程非常簡單:

  1. 當你觸發一個轉換時,API 會對目前頁面(舊狀態)進行「截圖」。
  2. 然後,你用 JavaScript 更新 DOM 到新狀態。
  3. API 會對新頁面(新狀態)也進行「截圖」。
  4. 最後,瀏覽器會在「舊截圖」和「新截圖」之間建立一個平滑的預設過渡動畫(通常是淡入淡出)。

這一切都由瀏覽器在底層高效處理,我們只需要呼叫一個簡單的函式。

3. 如何使用?

在單頁應用程式中,使用 View Transitions 非常簡單。只需將你的 DOM 更新邏輯包裹在 document.startViewTransition 函式中即可。

// 假设你有一个更新页面内容的函数
async function updatePageContent(url) {
  const response = await fetch(url);
  const newHtml = await response.text();
  // 用新内容替换旧内容 (具体实现取决于你的架构)
  document.body.innerHTML = newHtml;
}

// 在导航链接的点击事件中调用
document.querySelector('a').addEventListener('click', (event) => {
  event.preventDefault();
  const url = event.target.href;

  // 检查浏览器是否支持
  if (!document.startViewTransition) {
    updatePageContent(url); // 不支持则直接更新
    return;
  }

  // 使用 View Transition
  document.startViewTransition(() => updatePageContent(url));
});

僅僅這樣,你的頁面跳轉就會帶上一個預設的淡入淡出效果!

4. 自訂過渡動畫

預設的淡入淡出效果很棒,但 API 的真正威力在於其可自訂性。當 startViewTransition 執行時,瀏覽器會建立一個包含以下偽元素的 DOM 結構:

  • ::view-transition: 根元素,包含了整個過渡。
  • ::view-transition-old(root): 舊檢視的「截圖」。
  • ::view-transition-new(root): 新檢視的「截圖」。

我們可以透過 CSS animation 來覆蓋預設效果,例如實現一個滑入動畫:

@keyframes slide-in {
  from { transform: translateX(100%); }
}

::view-transition-new(root) {
  animation: slide-in 0.5s ease-out;
}

5. 元素間的「變形」:view-transition-name

API 最令人驚豔的功能是能夠讓兩個頁面中的 不同元素 被識別為 同一個物件,並在這兩個元素之間建立平滑的「變形」動畫。

這透過 view-transition-name 這個 CSS 屬性實現。

頁面 A(列表頁):

<img src="thumbnail.jpg" style="view-transition-name: hero-image;" />

頁面 B(詳細頁):

<img src="full-size.jpg" style="view-transition-name: hero-image;" />

當從頁面 A 跳轉到頁面 B 時,瀏覽器看到兩個元素的 view-transition-name 相同,它就會自動計算它們在位置、尺寸、形狀上的差異,並產生一個平滑的過渡動畫,而不是簡單的淡入淡出。這對於圖片、卡片等元素的過渡效果極佳。

結論

View Transitions API 為 Web 帶來了期待已久的原生過渡能力。它極大地簡化了過去需要複雜 JavaScript 動畫函式庫才能實現的互動效果,讓打造電影般流暢的應用程式體驗變得前所未有的簡單。隨著 Astro、Nuxt 等框架的整合,以及未來在多頁應用程式中的普及,它必將成為現代 Web 開發者的標準技能之一。