NavigateEvent: intercept() 方法

可用性有限

此特性不是基線特性,因為它在一些最廣泛使用的瀏覽器中不起作用。

實驗性: 這是一項實驗性技術
在生產中使用此技術之前,請仔細檢查瀏覽器相容性表格

NavigateEvent 介面的 intercept() 方法會攔截此次導航,並將其轉換為一次同文檔導航到 destination URL。

語法

js
intercept()
intercept(options)

引數

options 可選

一個包含以下屬性的選項物件

handler 可選

一個回撥函式,用於定義導航處理行為。通常處理資源獲取,並返回一個 Promise。

focusReset 可選

定義導航的焦點行為。它可以是以下值之一:

after-transition

一旦你的 handler 函式返回的 Promise 解析,瀏覽器將聚焦具有 autofocus 屬性的第一個元素,如果未設定 autofocus,則聚焦 <body> 元素。這是預設值。

manual

停用預設行為。

scroll 可選

定義導航的滾動行為。它可以是以下值之一:

after-transition

允許瀏覽器處理滾動,例如,如果 URL 包含片段識別符號,則滾動到相關片段;如果頁面被重新載入或歷史記錄中的頁面被再次訪問,則恢復到上次的滾動位置。這是預設值。

manual

停用預設行為。

返回值

無 (undefined)。

異常

InvalidStateError DOMException

如果當前 Document 尚未啟用,或者導航已被取消,則丟擲此錯誤。

SecurityError DOMException

如果事件是由 dispatchEvent() 呼叫分派的,而不是由使用者代理分派的,或者導航無法被攔截(即 NavigateEvent.canInterceptfalse),則丟擲此錯誤。

示例

使用 intercept() 處理導航

js
navigation.addEventListener("navigate", (event) => {
  // Exit early if this navigation shouldn't be intercepted,
  // e.g. if the navigation is cross-origin, or a download request
  if (shouldNotIntercept(event)) return;

  const url = new URL(event.destination.url);

  if (url.pathname.startsWith("/articles/")) {
    event.intercept({
      async handler() {
        // The URL has already changed, so show a placeholder while
        // fetching the new content, such as a spinner or loading page
        renderArticlePagePlaceholder();

        // Fetch the new content and display when ready
        const articleContent = await getArticleContent(url.pathname);
        renderArticlePage(articleContent);
      },
    });
  }
});

使用 focusResetscroll

可以透過查詢 NavigateEvent.formData 屬性來檢測表單提交。以下示例將任何表單提交轉換為保留在當前頁面的提交。在這種情況下,您不更新 DOM,因此可以使用 focusResetscroll 來取消任何預設的重置和滾動行為。

js
navigation.addEventListener("navigate", (event) => {
  if (event.formData && event.canIntercept) {
    // User submitted a POST form to a same-domain URL
    // (If canIntercept is false, the event is just informative:
    // you can't intercept this request, although you could
    // likely still call .preventDefault() to stop it completely).

    event.intercept({
      // Since we don't update the DOM in this navigation,
      // don't allow focus or scrolling to reset:
      focusReset: "manual",
      scroll: "manual",
      async handler() {
        await fetch(event.destination.url, {
          method: "POST",
          body: event.formData,
        });
        // You could navigate again with {history: 'replace'} to change the URL here,
        // which might indicate "done"
      },
    });
  }
});

規範

規範
HTML
# dom-navigateevent-intercept-dev

瀏覽器相容性

另見