1. 7.2 与导航和会话历史相关的 API
      1. 7.2.1 Window 对象
        1. 7.2.1.1 打开和关闭窗口
        2. 7.2.1.2 Window 对象上的索引访问
        3. 7.2.1.3 Window 对象上的命名访问
        4. 7.2.1.4 访问相关窗口
        5. 7.2.1.5 历史浏览器界面元素 API
      2. 7.2.2 WindowProxy 奇异对象
      3. 7.2.3 Location 接口
      4. 7.2.4 History 接口
      5. 7.2.5 导航 API
        1. 7.2.5.1 简介
        2. 7.2.5.2 Navigation 接口
        3. 7.2.5.3 核心基础设施
        4. 7.2.5.4 NavigationHistoryEntry 接口
        5. 7.2.5.5 历史条目列表
        6. 7.2.5.6 启动导航
        7. 7.2.5.7 正在进行的导航跟踪
        8. 7.2.5.8 NavigationActivation 接口
        9. 7.2.5.9 navigate 事件
          1. 7.2.5.9.1 NavigateEvent 接口
          2. 7.2.5.9.2 NavigationDestination 接口
      6. 7.2.6 事件接口
        1. 7.2.6.1 NavigationCurrentEntryChangeEvent 接口
        2. 7.2.6.2 PopStateEvent 接口
        3. 7.2.6.3 HashChangeEvent 接口
        4. 7.2.6.4 PageSwapEvent 接口
        5. 7.2.6.5 PageRevealEvent 接口
        6. 7.2.6.6 PageTransitionEvent 接口
        7. 7.2.6.7 BeforeUnloadEvent 接口
      7. 7.2.7 NotRestoredReasons 接口

7.2.1 Window 对象

Window

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge(旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
window.window
window.frames
window.self

这些属性都返回 window

window.document

返回与 window 关联的 Document

document.defaultView

如果存在,则返回与 document 关联的 Window,否则返回 null。

7.2.1.1 打开和关闭窗口
window = window.open([ url [, target [, features ] ] ])

打开一个窗口以显示 url(默认为“about:blank”),并返回它。 target(默认为“_blank”)给出新窗口的名称。如果一个窗口已经存在于该名称下,则会重用它。 features 参数可以包含一个逗号分隔的标记集

"noopener"
"noreferrer"

这些与 超链接 上的 noopenernoreferrer 链接类型等效。

"popup"

鼓励用户代理为新窗口提供最小的 Web 浏览器用户界面。(也影响所有 BarProp 对象上的 visible 获取器。)

globalThis.open("https://email.example/message/CAOOOkFcWW97r8yg=SsWg7GgCmp4suVX9o85y8BvNRqMjuc5PXg", undefined, "noopener,popup");
window.name [ = value ]

返回窗口的名称。

可以设置,以更改名称。

window.close()

关闭窗口。

window.closed

如果窗口已关闭,则返回 true,否则返回 false。

window.stop()

取消文档加载。

7.2.1.2 Window 对象上的索引访问
window.length

返回文档树子节点可导航对象的数量。

window[index]

返回对应于指示的文档树子节点可导航对象WindowProxy

7.2.1.3 Window 对象上的命名访问
window[name]

返回指示的元素或元素集合。

一般来说,依赖于此会导致代码脆弱。随着时间的推移,哪些 ID 最终映射到此 API 可能会发生变化,例如,当 Web 平台添加新功能时。不要使用此方法,而应使用 document.getElementById()document.querySelector()

window.top

返回顶级可遍历对象WindowProxy

window.opener [ = value ]

返回打开程序浏览上下文WindowProxy

如果没有或已设置为 null,则返回 null。

可以设置为 null。

window.parent

返回父可导航对象WindowProxy

window.frameElement

返回可导航容器元素。

如果没有或在跨源情况下,则返回 null。

7.2.1.5 历史浏览器界面元素 API

由于历史原因,Window 接口具有一些表示某些 Web 浏览器界面元素可见性的属性。

出于隐私和互操作性的原因,这些属性现在都返回相同的值:窗口是否表示弹出窗口。

window.locationbar.visible

BarProp/visible

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge(旧版)12+Internet Explorer不支持
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
window.menubar.visible
window.personalbar.visible
window.scrollbars.visible
window.statusbar.visible
window.toolbar.visible

如果 Window 不是弹出窗口,则返回 true;否则,返回 false。

7.2.2 WindowProxy 奇异对象

WindowProxy 是一种奇异对象,它包装了一个 Window 普通对象,并将大多数操作间接传递到包装的对象。每个浏览上下文都有一个关联的WindowProxy 对象。当浏览上下文导航时,浏览上下文关联的WindowProxy 对象包装的 Window 对象会发生变化。

7.2.3 Location 接口

Document/location

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge(旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Location

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge(旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

Window/location

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge(旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

每个 Window 对象都与一个唯一的 Location 对象实例关联,该实例在创建 Window 对象时分配。

document.location [ = value ]
window.location [ = value ]

返回一个具有当前页面位置的 Location 对象。

可以设置,以导航到另一个页面。

Location 对象提供了对其关联的 DocumentURL的表示形式,以及用于导航重新加载关联的可导航对象的方法。

location.toString()
location.href

返回Location对象的URL。

可以设置,以导航到给定的URL。

location.origin

返回Location对象的URL的源。

location.protocol

返回Location对象的URL的方案。

可以设置,以使用更改的方案导航到相同的URL。

location.host

返回Location对象的URL的主机和端口(如果与方案的默认端口不同)。

可以设置,以使用更改的主机和端口导航到相同的URL。

location.hostname

返回Location对象的URL的主机。

可以设置,以使用更改的主机导航到相同的URL。

location.port

返回Location对象的URL的端口。

可以设置,以使用更改的端口导航到相同的URL。

location.pathname

返回Location对象的URL的路径。

可以设置,以使用更改的路径导航到相同的URL。

location.search

返回Location对象的URL的查询(如果非空,则包括前导“?”)。

可以设置,以使用更改的查询导航到相同的URL(忽略前导“?”)。

location.hash

返回Location对象的URL的片段(如果非空,则包括前导“#”)。

可以设置,以使用更改的片段导航到相同的URL(忽略前导“#”)。

location.assign(url)

导航到给定的URL。

location.replace(url)

从会话历史记录中删除当前页面并导航到给定的URL。

location.reload()

重新加载当前页面。

location.ancestorOrigins

返回一个DOMStringList对象,其中列出了祖先可导航对象活动文档的源。

7.2.4 History 接口

历史记录

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

窗口/历史记录

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge(旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
history.length

返回当前可遍历可导航对象的全部会话历史记录条目的数量。

history.scrollRestoration

返回活动会话历史记录条目滚动恢复模式

history.scrollRestoration = value

活动会话历史记录条目滚动恢复模式设置为value

history.state

返回活动会话历史记录条目经典历史记录 API 状态,反序列化为 JavaScript 值。

history.go()

重新加载当前页面。

history.go(delta)

在当前可遍历可导航对象的全部会话历史记录条目列表中向后或向前移动指定步数。

零增量将重新加载当前页面。

如果增量超出范围,则不执行任何操作。

history.back()

在当前可遍历可导航对象的全部会话历史记录条目列表中后退一步。

如果没有上一页,则不执行任何操作。

history.forward()

在当前可遍历可导航对象的全部会话历史记录条目列表中前进一步。

如果没有下一页,则不执行任何操作。

history.pushState(data, "")

向会话历史记录中添加一个新条目,其经典历史记录 API 状态设置为data的序列化结果。活动历史记录条目URL将被复制并用于新条目的URL。

(第二个参数出于历史原因存在,不能省略;传递空字符串是传统做法。)

history.pushState(data, "", url)

向会话历史记录中添加一个新条目,其经典历史记录 API 状态设置为data的序列化结果,并且其URL设置为url

如果当前Document无法将其URL重写url,则会抛出"SecurityError"DOMException

(第二个参数出于历史原因存在,不能省略;传递空字符串是传统做法。)

history.replaceState(data, "")

活动会话历史记录条目经典历史记录 API 状态更新为data的结构化克隆。

(第二个参数出于历史原因存在,不能省略;传递空字符串是传统做法。)

history.replaceState(data, "", url)

活动会话历史记录条目经典历史记录 API 状态更新为data的结构化克隆,以及其URLurl

如果当前Document无法将其URL重写url,则会抛出"SecurityError"DOMException

(第二个参数出于历史原因存在,不能省略;传递空字符串是传统做法。)

documentURL目标URL 可以重写其URL
https://example.com/home https://example.com/home#about
https://example.com/home https://example.com/home?page=shop
https://example.com/home https://example.com/shop
https://example.com/home https://user:[email protected]/home
https://example.com/home http://example.com/home
file:///path/to/x file:///path/to/x#hash
file:///path/to/x file:///path/to/x?search
file:///path/to/x file:///path/to/y
about:blank about:blank#hash
about:blank about:blank?search
about:blank about:srcdoc
data:text/html,foo data:text/html,foo#hash
data:text/html,foo data:text/html,foo?search
data:text/html,foo data:text/html,bar
data:text/html,foo data:bar
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43#hash
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43?search
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:https://example.com/anything
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:path

请注意,只有DocumentURL才重要,而不是其。在诸如具有继承源的about:blank Document、沙盒化的iframe或使用document.domain设置器时,它们可能会不匹配。

考虑一个游戏,用户可以在一条线上导航,这样用户始终位于某个坐标处,并且用户可以将对应于特定坐标的页面添加为书签,以便以后返回。

实现此类游戏中x=5位置的静态页面可能如下所示

<!DOCTYPE HTML>
<!-- this is https://example.com/line?x=5 -->
<html lang="en">
<title>Line Game - 5</title>
<p>You are at coordinate 5 on the line.</p>
<p>
 <a href="?x=6">Advance to 6</a> or
 <a href="?x=4">retreat to 4</a>?
</p>

此类系统的问题在于,每次用户点击时,都需要重新加载整个页面。以下是另一种使用脚本的方法

<!DOCTYPE HTML>
<!-- this starts off as https://example.com/line?x=5 -->
<html lang="en">
<title>Line Game - 5</title>
<p>You are at coordinate <span id="coord">5</span> on the line.</p>
<p>
 <a href="?x=6" onclick="go(1); return false;">Advance to 6</a> or
 <a href="?x=4" onclick="go(-1); return false;">retreat to 4</a>?
</p>
<script>
 var currentPage = 5; // prefilled by server
 function go(d) {
   setupPage(currentPage + d);
   history.pushState(currentPage, "", '?x=' + currentPage);
 }
 onpopstate = function(event) {
   setupPage(event.state);
 }
 function setupPage(page) {
   currentPage = page;
   document.title = 'Line Game - ' + currentPage;
   document.getElementById('coord').textContent = currentPage;
   document.links[0].href = '?x=' + (currentPage+1);
   document.links[0].textContent = 'Advance to ' + (currentPage+1);
   document.links[1].href = '?x=' + (currentPage-1);
   document.links[1].textContent = 'retreat to ' + (currentPage-1);
 }
</script>

在没有脚本的系统中,这仍然像前面的示例一样工作。但是,确实支持脚本的用户现在可以更快地导航,因为对于相同的体验,没有网络访问。此外,与用户使用仅基于脚本的方法获得的体验相反,书签和导航会话历史记录仍然有效。

在上面的示例中,pushState()方法的data参数与发送到服务器的信息相同,但形式更方便,因此脚本不必每次用户导航时都解析URL。

大多数应用程序希望对所有历史记录条目使用相同的滚动恢复模式值。为了实现这一点,他们可以尽快设置scrollRestoration属性(例如,在文档的head元素中的第一个script元素中),以确保添加到历史记录会话中的任何条目都获得所需的滚动恢复模式。

<head>
  <script>
       if ('scrollRestoration' in history)
            history.scrollRestoration = 'manual';
  </script>
</head>
   

导航 API 由全局navigation属性提供,它提供了一种现代且以 Web 应用程序为中心的方式来管理导航和历史记录条目。它是经典locationhistory API 的后续版本。

API 提供的一种功能是检查会话历史记录条目。例如,以下操作将在有序列表中显示条目的 URL

const ol = document.createElement("ol");
ol.start = 0; // so that the list items' ordinal values match up with the entry indices

for (const entry of navigation.entries()) {
  const li = document.createElement("li");

  if (entry.index < navigation.currentEntry.index) {
    li.className = "backward";
  } else if (entry.index > navigation.currentEntry.index) {
    li.className = "forward";
  } else {
    li.className = "current";
  }

  li.textContent = entry.url;
  ol.append(li);
}

navigation.entries() 数组包含 NavigationHistoryEntry 实例,除了此处显示的 urlindex 属性之外,它们还具有其他有用的属性。请注意,该数组仅包含表示当前 可导航区域NavigationHistoryEntry 对象,因此其内容不受 可导航容器(例如 iframe)内部导航或在导航 API 本身在 iframe 内使用的情况下 父可导航区域 的导航的影响。此外,它仅包含表示相同 会话历史记录条目NavigationHistoryEntry 对象,这意味着如果用户在当前源之前或之后访问过其他源,则不会有相应的 NavigationHistoryEntry


导航 API 还可以用于导航、重新加载或遍历历史记录。

<button onclick="navigation.reload()">Reload</button>

<input type="url" id="navigationURL">
<button onclick="navigation.navigate(navigationURL.value)">Navigate</button>

<button id="backButton" onclick="navigation.back()">Back</button>
<button id="forwardButton" onclick="navigation.forward()">Forward</button>

<select id="traversalDestinations"></select>
<button id="goButton" onclick="navigation.traverseTo(traversalDestinations.value)">Traverse To</button>

<script>
backButton.disabled = !navigation.canGoBack;
forwardButton.disabled = !navigation.canGoForward;

for (const entry of navigation.entries()) {
  traversalDestinations.append(new Option(entry.url, entry.key));
}
</script>

请注意,遍历同样仅限于相同 的目标,这意味着,例如,如果前一个 会话历史记录条目 是来自另一个源的页面,则 navigation.canGoBack 将为 false。


导航 API 最强大的部分是 navigate 事件,它在当前 可导航区域 中发生几乎任何导航或遍历时都会触发。

navigation.onnavigate = event => {
  console.log(event.navigationType); // "push", "replace", "reload", or "traverse"
  console.log(event.destination.url);
  console.log(event.userInitiated);
  // ... and other useful properties
};

(如果导航是通过 地址栏 发起的导航,或者是从其他窗口发起的导航,并且导航的目标是新的文档,则该事件不会触发。)

大多数情况下,该事件的 cancelable 属性将为 true,这意味着可以使用 preventDefault() 取消此事件。

navigation.onnavigate = event => {
  if (event.cancelable && isDisallowedURL(event.destination.url)) {
    alert(`Please don't go to ${event.destination.url}!`);
    event.preventDefault();
  }
};

对于某些“traverse”导航,cancelable 属性将为 false,例如在 子可导航区域 内部发生的导航、跨越到新源的导航,或者当用户在之前调用 preventDefault() 阻止他们这样做后不久尝试再次遍历时。

NavigateEventintercept() 方法允许拦截导航并将其转换为相同文档的导航。

navigation.addEventListener("navigate", e => {
  // Some navigations, e.g. cross-origin navigations, we cannot intercept.
  // Let the browser handle those normally.
  if (!e.canIntercept) {
    return;
  }

  // Similarly, don't intercept fragment navigations or downloads.
  if (e.hashChange || e.downloadRequest !== null) {
    return;
  }

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

  if (url.pathname.startsWith("/articles/")) {
    e.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, { signal: e.signal });
        renderArticlePage(articleContent);
      }
    });
  }
});

请注意,handler 函数可以返回一个 Promise 来表示导航的异步进度以及成功或失败。在 Promise 仍处于挂起状态时,浏览器 UI 可以将导航视为正在进行中(例如,通过显示加载微调器)。导航 API 的其他部分也对这些 Promise 敏感,例如 navigation.navigate() 的返回值。

const { committed, finished } = await navigation.navigate("/articles/the-navigation-api-is-cool");

// The committed promise will fulfill once the URL has changed, which happens
// immediately (as long as the NavigateEvent wasn't canceled).
await committed;

// The finished promise will fulfill once the Promise returned by handler() has
// fulfilled, which happens once the article is downloaded and rendered. (Or,
// it will reject, if handler() fails along the way).
await finished;

以下是所有实现 Navigation 接口的对象作为 事件处理程序 IDL 属性 支持的 事件处理程序(及其对应的 事件处理程序事件类型)。

事件处理程序 事件处理程序事件类型
onnavigate navigate
onnavigatesuccess navigatesuccess
onnavigateerror navigateerror
oncurrententrychange currententrychange

导航 API 中广泛使用的一种关键类型是 NavigationType 枚举。

它捕获了主要对 Web 开发人员可见的“导航”类型,这些类型(如 其他地方所述)并不完全对应于此标准的唯一 navigate 算法。每个值的含义如下:

"push"
对应于 navigate 的调用,其中 历史记录处理行为 最终变为 "push",或对应于 history.pushState()
"replace"
对应于 navigate 的调用,其中 历史记录处理行为 最终变为 "replace",或对应于 history.replaceState()
"reload"
对应于 reload 的调用。
"traverse"
对应于 根据增量遍历历史记录 的调用。
7.2.5.4 NavigationHistoryEntry 接口
entry.url

此导航历史记录条目的 URL。

如果条目对应于与当前条目不同的 Document(即,如果 sameDocument 为 false),并且该 Document 是使用“no-referrer”或“origin”的 referrer 策略 获取的,则它可以返回 null,因为这表示所讨论的 Document 甚至对其他相同源页面也隐藏其 URL。

entry.key

用户代理生成的随机 UUID 字符串,表示此导航历史记录条目在导航历史记录列表中的位置。由于“replace”导航,此值将被其他替换此条目的 NavigationHistoryEntry 实例重用,并且将在重新加载和会话恢复后继续存在。

这对于使用 navigation.traverseTo(key) 导航回导航历史记录列表中的此条目很有用。

entry.id

用户代理生成的随机 UUID 字符串,表示此特定的导航历史记录条目。此值 *不会* 被其他 NavigationHistoryEntry 实例重用。此值将在重新加载和会话恢复后继续存在。

这对于使用其他存储 API 将数据与此导航历史记录条目关联很有用。

entry.index

NavigationHistoryEntrynavigation.entries() 中的索引,或者如果条目不在导航历史记录条目列表中,则为 −1。

entry.sameDocument

指示此导航历史记录条目是否与当前条目属于同一个 Document。例如,当条目表示片段导航或单页应用程序导航时,这将为 true。

entry.getState()

返回存储在此条目中的状态的 反序列化,该状态是使用 navigation.navigate()navigation.updateCurrentEntry() 添加到条目的。此状态将在重新加载和会话恢复后继续存在。

请注意,通常情况下,除非状态值是基本类型,否则 entry.getState() !== entry.getState(),因为每次都会返回新的反序列化结果。

此状态与经典历史记录 API 的 history.state 无关。

以下是所有实现 NavigationHistoryEntry 接口的对象作为 事件处理程序 IDL 属性 支持的 事件处理程序(及其对应的 事件处理程序事件类型)。

事件处理程序 事件处理程序事件类型
ondispose dispose
7.2.5.5 历史记录条目列表
entries = navigation.entries()

返回一个 NavigationHistoryEntry 实例数组,表示当前导航历史记录条目列表,即此 可导航区域 的所有 会话历史记录条目,这些条目与 当前会话历史记录条目 属于相同 且是连续的。

navigation.currentEntry

返回对应于 当前会话历史记录条目NavigationHistoryEntry

navigation.updateCurrentEntry({ state })

更新 当前会话历史记录条目导航 API 状态,而无需执行像 navigation.reload() 那样执行导航。

此方法最适合捕获已发生的页面更新,并需要将其反映到导航 API 状态中。对于旨在驱动页面更新的状态更新情况,请改用 navigation.navigate()navigation.reload(),它们将触发 navigate 事件。

navigation.canGoBack

如果当前的当前会话历史条目(即 currentEntry)不是导航历史条目列表中的第一个(即在 entries() 中)。这意味着对于此可导航对象,存在一个之前的会话历史条目,并且其文档状态来源与当前Document来源同源的。

navigation.canGoForward

如果当前的当前会话历史条目(即 currentEntry)不是导航历史条目列表中的最后一个(即在 entries() 中)。这意味着对于此可导航对象,存在一个下一个会话历史条目,并且其文档状态来源与当前Document来源同源的。

{ 已提交, 已完成 } = navigation.navigate(url)
{ 已提交, 已完成 } = navigation.navigate(url, options)

将当前页面导航到给定的urloptions可以包含以下值

默认情况下,这将执行完整导航(即跨文档导航,除非给定的 URL 仅在片段方面与当前 URL 不同)。navigateEvent.intercept()方法可用于将其转换为同文档导航。

返回的 Promise 将按以下方式运行

在所有情况下,当返回的 Promise 完成时,它将与已导航到的NavigationHistoryEntry一起完成。

{ 已提交, 已完成 } = navigation.reload(options)

重新加载当前页面。 options可以包含infostate,其行为如上所述。

可以通过使用navigateEvent.intercept()方法覆盖执行当前页面从网络或缓存重新加载的默认行为。这样做意味着此调用仅更新状态或传递适当的info,以及执行navigate事件处理程序认为合适的任何操作。

返回的 Promise 将按以下方式运行

{ 已提交, 已完成 } = navigation.traverseTo(key)
{ 已提交, 已完成 } = navigation.traverseTo(key, { info })

遍历到与具有给定keyNavigationHistoryEntry匹配的最接近的会话历史条目info可以设置为任何值;它将填充相应NavigateEventinfo属性。

如果到该会话历史条目的遍历已在进行中,则这将返回该原始遍历的 Promise,并且info将被忽略。

返回的 Promise 将按以下方式运行

{ 已提交, 已完成 } = navigation.back(key)
{ 已提交, 已完成 } = navigation.back(key, { info })

遍历到导致此可导航对象遍历的最接近的先前会话历史条目,即对应于不同的NavigationHistoryEntry,因此将导致navigation.currentEntry更改。 info可以设置为任何值;它将填充相应NavigateEventinfo属性。

如果到该会话历史条目的遍历已在进行中,则这将返回该原始遍历的 Promise,并且info将被忽略。

返回的 Promise 的行为等同于traverseTo()返回的 Promise。

{ 已提交, 已完成 } = navigation.forward(key)
{ 已提交, 已完成 } = navigation.forward(key, { info })

遍历到导致此可导航对象遍历的最接近的前进会话历史条目,即对应于不同的NavigationHistoryEntry,因此将导致navigation.currentEntry更改。 info可以设置为任何值;它将填充相应NavigateEventinfo属性。

如果到该会话历史条目的遍历已在进行中,则这将返回该原始遍历的 Promise,并且info将被忽略。

返回的 Promise 的行为等同于traverseTo()返回的 Promise。

7.2.5.7 正在进行的导航跟踪
navigation.transition

一个NavigationTransition,表示任何尚未到达navigatesuccessnavigateerror阶段的正在进行的导航(如果存在);或者如果不存在此类正在进行的转换,则为 null。

由于navigation.currentEntry(以及其他属性,例如location.href)在导航时会立即更新,因此此navigation.transition属性对于根据传递给navigateEvent.intercept()的任何处理程序确定此类导航何时尚未完全完成很有用。

navigation.transition.navigationType

表示此转换所属的导航类型之一,取值为“push”、“replace”、“reload”或“traverse”。

navigation.transition.from

转换源自的NavigationHistoryEntry。这可以用来与navigation.currentEntry进行比较。

navigation.transition.finished

一个 Promise,其完成时间与navigatesuccess事件触发的时间相同,或者其拒绝时间与navigateerror事件触发的时间相同。

navigation.activation

一个包含最近一次跨文档导航信息的NavigationActivation,该导航“激活”了此Document

虽然navigation.currentEntryDocumentURL可能会由于同文档导航而定期更新,但navigation.activation保持不变,并且其属性仅在从历史记录中重新激活Document时更新。

navigation.activation.entry

一个NavigationHistoryEntry,等效于Document被激活时navigation.currentEntry属性的值。

navigation.activation.from

一个NavigationHistoryEntry,表示当前Document之前处于活动状态的Document。如果前一个Document与当前Document同源或为初始about:blankDocument,则此属性的值为null。

在某些情况下,fromentry NavigationHistoryEntry对象可能不是traverseTo()方法的可行目标,因为它们可能不会保留在历史记录中。例如,可以使用location.replace()激活Document,或者其初始条目可能会被history.replaceState()替换。但是,这些条目的url属性和getState()方法仍然可访问。

navigation.activation.navigationType

表示激活此Document的导航类型之一,取值为“push”、“replace”、“reload”或“traverse”。

每个Navigation都有一个关联的activation,它可以是null或NavigationActivation对象,初始值为null。

每个NavigationActivation都有

activation 获取器步骤是返回thisactivation

from 获取器步骤是返回this旧条目

entry 获取器步骤是返回this新条目

navigationType 获取器步骤是返回this导航类型

7.2.5.9 navigate 事件

导航 API 的一个主要功能是navigate事件。此事件在任何导航(广义上的)中触发,允许 Web 开发人员监视此类传出导航。在许多情况下,该事件是可取消的,这允许阻止导航发生。在其他情况下,可以使用NavigateEvent类的intercept()方法拦截导航并将其替换为同文档导航。

7.2.5.9.1 NavigateEvent 接口
event.navigationType

表示此导航类型的其中之一,取值为“push”、“replace”、“reload”或“traverse”。

event.destination

一个表示导航目标的NavigationDestination

event.canIntercept

如果可以调用intercept()以拦截此导航并将其转换为同文档导航,从而替换其通常的行为,则为true;否则为false。

一般来说,只要当前Document可以将其 URL 重写为目标 URL,这将为 true,但跨文档“traverse”导航除外,在这种情况下,它始终为 false。

event.userInitiated

如果此导航是由于用户单击a元素、提交form元素或使用浏览器 UI导航引起的,则为true;否则为false。

event.hashChange

对于片段导航为true;否则为false。

event.signal

一个AbortSignal,如果导航被取消(例如,用户按下浏览器的“停止”按钮或另一个导航中断此导航),则此信号将被中止。

预期模式是开发人员将其传递给任何异步操作(例如fetch()),他们作为处理此导航的一部分执行这些操作。

event.formData

如果此导航是表示 POST 表单提交的“push”或“replace”导航,则表示提交的表单条目的FormData;否则为null。

(值得注意的是,即使对于重新访问最初由表单提交创建的会话历史记录条目的“reload”或“traverse”导航,此属性也将为null。)

event.downloadRequest

表示是否通过使用aarea元素的download属性请求此导航为下载。

请注意,请求下载并不总是意味着会发生下载:例如,下载可能会被浏览器安全策略阻止,或最终被视为未指定原因的“push”导航。

同样,即使没有请求导航为下载,导航也可能最终成为下载,这是因为目标服务器使用`Content-Disposition: attachment` 标头进行响应。

最后,请注意,如果使用浏览器 UI 功能(例如,右键单击并选择保存链接的目标)启动下载,则navigate事件根本不会触发。

event.info

通过发起此导航的导航 API 方法之一传递的任意 JavaScript 值,如果导航是由用户或其他 API 发起的,则为 undefined。

event.hasUAVisualTransition

如果用户代理在分派此事件之前为此导航执行了视觉转换,则返回 true。如果为 true,则如果作者同步将 DOM 更新到导航后状态,则将提供最佳用户体验。

event.intercept({ handler, focusReset, scroll })

拦截此导航,阻止其正常处理,而是将其转换为与目标 URL 相同类型且在同一文档中的导航。

handler选项可以是一个返回 promise 的函数。在navigate事件完成触发并且navigation.currentEntry属性已同步更新后,将运行处理程序函数。此返回的 promise 用于指示导航的持续时间以及成功或失败。在它完成之后,浏览器会向用户发出信号(例如,通过加载微调器 UI 或辅助技术)表示导航已完成。此外,它将根据需要触发navigatesuccessnavigateerror事件,Web 应用程序的其他部分可以对此做出响应。

默认情况下,使用此方法将在任何处理程序返回的 promise 完成时导致焦点重置。焦点将重置为设置了autofocus属性的第一个元素,或者如果不存在该属性,则重置为body 元素。可以将focusReset选项设置为“manual”以避免此行为。

默认情况下,使用此方法将延迟浏览器针对“traverse”或“reload”导航的滚动恢复逻辑,或其针对“push”或“replace”导航的滚动重置/滚动到片段逻辑,直到任何处理程序返回的 promise 完成。可以将scroll选项设置为“manual”以完全关闭此导航的任何浏览器驱动的滚动行为,或者可以在 promise 完成之前调用scroll()以尽早触发此行为。

如果canIntercept为 false,或者如果isTrusted为 false,则此方法将抛出一个"SecurityError"DOMException。如果不在事件分派期间同步调用,则会抛出一个"InvalidStateError"DOMException

event.scroll()

对于“traverse”或“reload”导航,使用浏览器的常用滚动恢复逻辑恢复滚动位置。

对于“push”或“replace”导航,要么将滚动位置重置到文档顶部,要么滚动到destination.url指定的片段(如果存在)。

如果多次调用,或者在由于scroll选项保留为“after-transition”而发生自动导航后滚动处理后调用,或者在导航已提交之前调用,则此方法将抛出一个"InvalidStateError"DOMException

7.2.5.9.2 NavigationDestination 接口
event.destination.url

要导航到的 URL。

event.destination.key

目标NavigationHistoryEntrykey属性的值,如果这是“traverse”导航,否则为空字符串。

event.destination.id

目标NavigationHistoryEntryid属性的值,如果这是“traverse”导航,否则为空字符串。

event.destination.index

目标NavigationHistoryEntryindex属性的值,如果这是“traverse”导航,否则为 -1。

event.destination.sameDocument

指示此导航是否与当前导航位于同一个Document中。例如,在片段导航或history.pushState()导航的情况下,这将为 true。

请注意,此属性指示导航的原始性质。如果使用navigateEvent.intercept()将跨文档导航转换为同一文档导航,则不会更改此属性的值。

event.destination.getState()

对于“traverse”导航,返回存储在目标会话历史条目中的状态的反序列化

对于“push”或“replace”导航,返回传递给navigation.navigate()的状态的反序列化,如果导航是由该方法发起的,否则为 undefined。

对于“reload”导航,返回传递给navigation.reload()的状态的反序列化,如果重新加载是由该方法发起的,否则为 undefined。

由于其复杂性,NavigateEvent接口有其自己的专用部分

7.2.6.1 NavigationCurrentEntryChangeEvent 接口
event.navigationType

返回导致当前条目更改的导航类型,如果更改是由于navigation.updateCurrentEntry()导致的,则返回 null。

event.from

返回当前条目更改之前navigation.currentEntry的先前值。

如果navigationType为 null 或“reload”,则此值将与navigation.currentEntry相同。在这种情况下,事件表示条目的内容已更改,即使我们没有移动到新条目或替换当前条目。

7.2.6.2 PopStateEvent 接口

PopStateEvent/PopStateEvent

所有当前引擎都支持。

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (Legacy)14+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

PopStateEvent

所有当前引擎都支持。

Firefox4+Safari6+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
event.state

返回提供给pushState()replaceState()的信息的副本。

event.hasUAVisualTransition

如果用户代理在分派此事件之前为此导航执行了视觉转换,则返回 true。如果为 true,则如果作者同步将 DOM 更新到导航后状态,则将提供最佳用户体验。

7.2.6.3 HashChangeEvent 接口

HashChangeEvent/HashChangeEvent

所有当前引擎都支持。

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge(旧版)12+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HashChangeEvent

所有当前引擎都支持。

Firefox3.6+Safari5+Chrome8+
Opera10.6+Edge79+
Edge (Legacy)12+Internet Explorer8+
Firefox AndroidSafari iOS5+Chrome AndroidWebView AndroidSamsung InternetOpera Android11+
event.oldURL

返回先前处于活动状态的URL对应的会话历史记录条目

event.newURL

返回当前处于活动状态的URL对应的会话历史记录条目

7.2.6.4 PageSwapEvent 接口
event.activation

一个NavigationActivation对象,表示跨文档导航的目标和类型。对于跨源导航,这将为 null。

event.activation.entry

一个NavigationHistoryEntry,表示即将激活的Document

event.activation.from

一个NavigationHistoryEntry,等价于事件触发时navigation.currentEntry属性的值。

event.activation.navigationType

以下字符串之一:“push”、“replace”、“reload”或“traverse”,指示即将导致页面切换的导航类型。

event.viewTransition

返回表示出站跨文档视图转换的ViewTransition对象(如果事件触发时此类转换处于活动状态)。否则,返回 null。

7.2.6.5 PageRevealEvent 接口
event.viewTransition

返回表示入站跨文档视图转换的ViewTransition对象(如果事件触发时此类转换处于活动状态)。否则,返回 null。

7.2.6.6 PageTransitionEvent 接口

PageTransitionEvent/PageTransitionEvent

所有当前引擎都支持。

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (Legacy)Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

PageTransitionEvent

所有当前引擎都支持。

Firefox1.5+Safari5+Chrome4+
Opera?Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox AndroidSafari iOS4+Chrome AndroidWebView Android37+Samsung InternetOpera Android
event.persisted

对于pageshow事件,如果页面正在加载(并且将触发load事件),则返回 false。否则,返回 true。

对于pagehide事件,如果页面即将最后一次消失,则返回 false。否则,返回 true,这意味着如果用户导航回此页面,则可能会重用该页面(如果Document可保存状态保持为 true)。

可能导致页面无法保存的事项包括

7.2.6.7 BeforeUnloadEvent 接口

BeforeUnloadEvent

所有当前引擎都支持。

Firefox1.5+Safari7+Chrome30+
Opera?Edge79+
Edge (Legacy)Internet Explorer4+
Firefox AndroidSafari iOSChrome AndroidWebView Android37+Samsung Internet3.0+Opera Android

没有BeforeUnloadEvent特有的初始化方法。

BeforeUnloadEvent接口是一个旧版接口,它允许检查是否取消卸载不仅可以通过取消事件来控制,还可以通过将returnValue属性设置为除空字符串以外的值来控制。作者应该使用preventDefault()方法或其他取消事件的方法,而不是使用returnValue

7.2.7 NotRestoredReasons 接口

notRestoredReasonDetails.reason

返回一个字符串,解释阻止文档从回退/前进缓存中提供服务的原因。有关可能的字符串值,请参阅bfcache 阻止详细信息的定义。

notRestoredReasons.src

如果文档的节点可导航容器iframe元素,则返回该元素的src属性。如果没有设置或它不是iframe元素,则这可以为 null。

notRestoredReasons.id

如果文档的节点可导航容器iframe元素,则返回该元素的id属性。如果没有设置或它不是iframe元素,则这可以为 null。

notRestoredReasons.name

如果文档的节点可导航容器iframe元素,则返回该元素的name属性。如果没有设置或它不是iframe元素,则这可以为 null。

notRestoredReasons.url

返回文档的URL,或者如果文档位于跨源iframe中则返回 null。除了src之外,还会报告此信息,因为iframe自设置原始src以来可能已导航。

notRestoredReasons.reasons

返回文档的NotRestoredReasonDetails数组。如果文档位于跨源iframe中,则这为 null。

notRestoredReasons.children

返回文档子元素的NotRestoredReasons数组。如果文档位于跨源iframe中,则这为 null。

NotRestoredReasonDetails对象有一个后备结构,一个未恢复原因详细信息或 null,最初为 null。

reason获取器步骤是返回this的后备结构的reason

给定未恢复原因详细信息backingStruct领域realm创建NotRestoredReasonDetails对象

  1. notRestoredReasonDetails为在realm中创建的新NotRestoredReasonDetails对象。

  2. notRestoredReasonDetails的后备结构设置为backingStruct

  3. 返回notRestoredReasonDetails

未恢复原因详细信息是一个具有以下结构

reason是一个表示阻止页面从回退/前进缓存中恢复的原因的字符串。该字符串是以下字符串之一:

"fetch"
在卸载过程中,此Document发起的 fetch 仍在进行中并被取消,因此页面处于无法存储在回退/前进缓存中的不稳定状态。

"navigation-failure"
创建此Document的原始导航发生错误,因此阻止了将生成的错误文档存储在前进/后退缓存中。
"parser-aborted"
Document从未完成其初始 HTML 解析,因此阻止了将未完成的文档存储在前进/后退缓存中。
"websocket"
在卸载期间,一个打开的WebSocket连接被关闭,因此页面处于无法存储在前进/后退缓存中的不稳定状态。 [WEBSOCKETS]
"lock"
在卸载期间,持有的锁请求被终止,因此页面处于无法存储在前进/后退缓存中的不稳定状态。 [WEBLOCKS]
"masked"
Document具有位于跨源iframe中的子元素,并且它们阻止了前进/后退缓存;或者此Document由于用户代理特定原因而无法前进/后退缓存

一个NotRestoredReasons对象具有一个后备结构,一个未恢复原因或null,初始值为null。

一个NotRestoredReasons对象具有一个原因数组,一个FrozenArray<NotRestoredReasonDetails>或null,初始值为null。

一个NotRestoredReasons对象具有一个子元素数组,一个FrozenArray<NotRestoredReasons>或null,初始值为null。

src获取器的步骤是返回this的后备结构的src

id获取器的步骤是返回this的后备结构的id

name获取器的步骤是返回this的后备结构的name

url获取器的步骤是

  1. 如果this的后备结构的URL为null,则返回null。

  2. 返回this的后备结构的URL序列化后的结果。

reasons获取器的步骤是返回this的原因数组。

children获取器的步骤是返回this的子元素数组。

给定一个未恢复原因backingStruct和一个realm创建一个NotRestoredReasons对象

  1. notRestoredReasons为在realm中创建的一个新的NotRestoredReasons对象。

  2. notRestoredReasons的后备结构设置为backingStruct

  3. 如果backingStructreasons为null,则将notRestoredReasons的原因数组设置为null。

  4. 否则

    1. reasonsArray为一个空的列表

    2. 对于backingStructreasons中的每个reason

      1. 给定reasonrealm创建一个NotRestoredReasonDetails对象,并将其附加reasonsArray中。

    3. notRestoredReasons的原因数组设置为给定reasonsArray创建冻结数组的结果。

  5. 如果backingStructchildren为null,则将notRestoredReasons的子元素数组设置为null。

  6. 否则

    1. childrenArray为一个空的列表

    2. 对于backingStructchildren中的每个child

      1. 给定childrealm创建一个NotRestoredReasons对象,并将其附加childrenArray中。

    3. notRestoredReasons的子元素数组设置为给定childrenArray创建冻结数组的结果。

  7. 返回notRestoredReasons

一个未恢复原因是一个具有以下结构体

一个Document的未恢复原因是其节点可导航活动会话历史记录条目文档状态未恢复原因,如果Document节点可导航是一个顶级可遍历;否则为null。