NavigateEvent: intercept() 方法

实验性: 这是一种 实验性技术
在生产环境中使用之前,请仔细查看 浏览器兼容性表格

intercept() 方法是 NavigateEvent 接口的方法,它拦截此导航,将其转换为指向 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

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载

另请参阅