題目與使用場景
網站使用普通連結在同源頁面間導覽,頁面由伺服器渲染,不能為了動畫改成單頁應用程式。設計目標是在支援 View Transition API 的瀏覽器中提供連續轉場,不支援時仍沿用原生導覽。回答應涵蓋同文件和跨文件兩種機制、狀態更新失敗、歷史導覽、焦點、捲動位置與減少動畫偏好。
面試官考察什麼
- 能否區分
document.startViewTransition()的同文件更新和@view-transition觸發的跨文件導覽。 - 是否理解 API 只是增強層,不能取代連結、歷史記錄和伺服器渲染。
- 是否會用能力偵測、失敗回退和
prefers-reduced-motion控制風險。 - 是否能驗證動畫偽元素、焦點管理、慢裝置和中斷導覽。
作答前的澄清問題
先確認導覽是否始終同源、是否包含 iframe、是否需要共享元素動畫,以及網站是否已有客戶端路由。再確認目標瀏覽器範圍、動畫時長要求、是否允許只做淡入淡出,以及使用者關閉動畫後的產品約束。跨文件轉場要求目前頁和目標頁都選擇加入,且瀏覽器支援該能力;不能把它當作跨域導覽方案。
30 秒回答框架
我會保留原生連結和伺服器導覽,把轉場當作漸進增強。同頁局部更新使用能力偵測包裹 startViewTransition;多頁同源導覽在兩頁宣告 @view-transition。更新回呼失敗時讓頁面保持可用並記錄錯誤。動畫只作用於視圖偽元素,遵守減少動畫偏好,焦點、捲動和歷史語意由正常導覽負責。最後用無支援瀏覽器、回退、前進、慢網和中斷場景驗收。
分步驟深入解答
- 建立不依賴動畫的基線。 連結、表單提交、伺服器回應和錯誤頁先獨立可用;不要用腳本攔截所有導覽來模擬效果。
- 處理同文件更新。 對列表篩選或局部狀態變化,偵測
document.startViewTransition。支援時在回呼中更新 DOM,不支援時直接執行同一更新函式。回呼拋錯時讓呼叫方顯示原有錯誤狀態。 - 處理跨文件導覽。 在同源頁面的樣式中宣告
@view-transition { navigation: auto; },由瀏覽器在導覽期間建立轉場;不呼叫startViewTransition。兩頁缺一宣告或能力不足時,仍走普通導覽。 - 控制轉場邊界。 只給確實對應的元素設定
view-transition-name,避免重複名稱導致快照衝突。使用::view-transition-old與::view-transition-new調整淡入淡出,動畫時長保持短且可中斷。 - 保護可及性。
@media (prefers-reduced-motion: reduce)下關閉或縮短動畫;導覽完成後確認焦點落到新頁面的主標題或合理位置,不能依賴截圖偽元素傳達狀態。 - 處理執行期狀態。 前進、後退、重新整理、網路失敗、重複點擊和使用者離開頁面都要有正常結果。轉場只改變視覺時序,不改變 URL、快取、權限或資料提交語意。
高品質示範回答
我會把實作拆成「原生導覽基線」和「可選動畫層」。對同文件更新,所有瀏覽器共用一個 update 函式;支援 API 時呼叫 document.startViewTransition(update),否則直接呼叫 update。對伺服器渲染的多頁導覽,在同源頁面加入 @view-transition { navigation: auto; },不攔截連結,也不假設跨域可用。
動畫只負責視覺連續性。頁面結構用穩定的 view-transition-name 標記,預設使用短淡入淡出,減少動畫偏好下關閉它。新頁面仍透過真實回應完成焦點、捲動和錯誤處理。測試涵蓋不支援 API、回呼拋錯、後退前進、重複點擊、慢 CPU、慢網路、切換分頁和減少動畫偏好。依據包括 MDN 的 View Transition API 與 startViewTransition 文件,以及 Chrome for Developers 的跨文件指南。
常見錯誤
- 把跨文件導覽寫成呼叫
startViewTransition;該方法用於同文件,跨文件由導覽和 CSS 選擇加入。 - 用腳本阻止所有連結,導致鍵盤、複製連結、後退和無腳本存取退化。
- 假設所有瀏覽器或 iframe 都支援相同能力,沒有能力偵測和普通導覽回退。
- 為大量元素設定重複名稱,或讓動畫持續太久,造成快照衝突和使用者迷失。
- 只測試順向點擊,沒有測試失敗回應、前進後退、減少動畫偏好和動畫被中斷的情況。
追問及應對
如果同文件更新回呼失敗怎麼辦?
把 DOM 更新和錯誤狀態設計成可獨立執行的函式。捕獲 ViewTransition 的例外只用於記錄和收斂動畫狀態,業務錯誤仍按原有 UI 顯示,不能讓動畫例外阻斷資料更新。
如何驗證跨文件轉場沒有改變導覽語意?
在支援與不支援的瀏覽器分別檢查 URL、歷史堆疊、重新整理、複製連結開啟、鍵盤操作、焦點落點和伺服器錯誤頁。關閉 CSS 轉場後,頁面結果應完全一致。
何時不應該使用共享元素動畫?
當元素身分不穩定、列表頻繁重排、內容含強烈運動或使用者需要立即定位狀態時,使用簡單淡入淡出或完全關閉動畫。視覺收益不足以抵消焦點、效能和理解成本時,應保留原生體驗。