Chrome 105 版中的 NavigationEvent 異動

Joe Medley
Joe Medley

Chrome 105 在 Navigation API 的 NavigateEvent 中推出了兩種新方法 (在 102 版推出),以改善在實際操作中已證實有問題的方法。intercept() 可讓開發人員控制導覽後的狀態,取代難以使用的 transitionWhile()scroll() 方法會捲動至網址中指定的錨點,取代無法用於所有導覽類型的 restoreScroll()

本文將說明這兩種方法的問題,以及新方法如何解決這些問題。

NavigateEvent.trasitionWhile() 方法是在 Chrome 102 中與 Navigation API 一併推出,可攔截單頁應用程式中用於用戶端轉場的導覽。其第一個引數是承諾,可向瀏覽器和網頁應用程式的其他部分發出完成信號。

但實際上效果不佳。請考慮使用這個常見的程式設計模式:

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

這與下列程式碼的功能相同。這會導致部分導覽作業在 API 察覺開發人員打算攔截導覽之前就執行。

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

這可能會導致捲動還原邏輯擷取 DOM 變更後的捲動位置,而非擷取變更前的捲動位置,進而導致應用程式發生錯誤。

異動情形

為了取代 transitionWhile(),目前的規格引入了 NavigateEvent.intercept()。除了 transitionWhile() 支援的 focusResetscrollRestoration 屬性外,新方法還會採用處理常式。新的處理常式一律會在導覽提交後執行,並擷取捲動位置等內容,避免 transitionWhile() 發生問題。

transitionWhile() 方法仍可使用,但已遭淘汰,並將在 Chrome 108 中移除。

使用 intercept()

NavigateEvent.intercept()transitionWhile() 有相同的限制,無法在所有導覽事件上呼叫。無法攔截跨來源導覽,也無法攔截跨文件的檢索作業。這麼做會擲回 "SecurityError" 類型的 DOMException

如要使用 intercept(),請在呼叫時傳遞自訂處理常式。

navigation.addEventListener("navigate", event => {
  event.intercept({
    async handler() {
      doSyncStuff();
      await doAsyncStuff();
    }
  });
});

即使是在單頁應用程式中,瀏覽器也會完全處理導覽作業,例如從頁面頂端前往錨點 (從 /a 移動到 /a#id)。不過,如果要前往另一個「頁面」上的錨點 (從 /a 移動到 /b#id),雖然在多頁應用程式中很簡單,但在單頁應用程式中則較為複雜。應用程式必須使用 NavigateEvent.transitionWhile() 攔截導向 /b#id 的導覽,然後呼叫 NavigateEvent.restoreScroll() 將錨點帶入檢視畫面。如上所述,目前很難做到這點。

異動情形

在單頁應用程式中,您現在可以控制瀏覽器是否要處理捲動至錨點的動作,或是由程式碼處理。

使用 scroll()

根據預設,一旦攔截處理程序完成,瀏覽器就會嘗試自動處理捲動作業。如果您想自行處理捲動,請將 scroll 設為 "manual",然後在瀏覽器嘗試設定捲動位置時呼叫 NavigateEvent.scroll()

navigation.addEventListener("manual", event => {
  scroll: "manual",
  event.intercept({
    async handler() {
      doSyncStuff();
      // Handle scrolling earlier than by default:
      event.scroll();
      await doAsyncStuff();
    }
  });
});

restoreScroll() 方法仍可使用,但已遭淘汰,並將在 Chrome 108 中移除。

結論

我們希望能盡快更新 Navigation API 相關文章。在此同時,這個 API 的規格包含許多專門給網頁開發人員的資訊。

相片來源:Tim Gouw 提供,取自 Unsplash