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

浏览器兼容性

另见