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 版中移除。

使用 截距()

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