1. 7.2 与导航和会话历史相关的 API
      1. 7.2.1 WindowWindowProxyLocation 对象的安全基础设施
        1. 7.2.1.1 与 IDL 的集成
        2. 7.2.1.2 共享内部槽位:[[CrossOriginPropertyDescriptorMap]]
        3. 7.2.1.3 共享抽象操作
          1. 7.2.1.3.1 CrossOriginProperties ( O )
          2. 7.2.1.3.2 CrossOriginPropertyFallback ( P )
          3. 7.2.1.3.3 IsPlatformObjectSameOrigin ( O )
          4. 7.2.1.3.4 CrossOriginGetOwnPropertyHelper ( O, P )
          5. 7.2.1.3.5 CrossOriginGet ( O, P, Receiver )
          6. 7.2.1.3.6 CrossOriginSet ( O, P, V, Receiver )
          7. 7.2.1.3.7 CrossOriginOwnPropertyKeys ( O )
      2. 7.2.2 Window 对象
        1. 7.2.2.1 打开和关闭窗口
        2. 7.2.2.2 Window 对象上的索引访问
        3. 7.2.2.3 Window 对象上的命名访问
        4. 7.2.2.4 访问相关窗口
        5. 7.2.2.5 历史浏览器接口元素 API
        6. 7.2.2.6 Window 对象的脚本设置
      3. 7.2.3 WindowProxy 外来对象
        1. 7.2.3.1 [[GetPrototypeOf]] ( )
        2. 7.2.3.2 [[SetPrototypeOf]] ( V )
        3. 7.2.3.3 [[IsExtensible]] ( )
        4. 7.2.3.4 [[PreventExtensions]] ( )
        5. 7.2.3.5 [[GetOwnProperty]] ( P )
        6. 7.2.3.6 [[DefineOwnProperty]] ( P, Desc )
        7. 7.2.3.7 [[Get]] ( P, Receiver )
        8. 7.2.3.8 [[Set]] ( P, V, Receiver )
        9. 7.2.3.9 [[Delete]] ( P )
        10. 7.2.3.10 [[OwnPropertyKeys]] ( )
      4. 7.2.4 Location 接口
        1. 7.2.4.1 [[GetPrototypeOf]] ( )
        2. 7.2.4.2 [[SetPrototypeOf]] ( V )
        3. 7.2.4.3 [[IsExtensible]] ( )
        4. 7.2.4.4 [[PreventExtensions]] ( )
        5. 7.2.4.5 [[GetOwnProperty]] ( P )
        6. 7.2.4.6 [[DefineOwnProperty]] ( P, Desc )
        7. 7.2.4.7 [[Get]] ( P, Receiver )
        8. 7.2.4.8 [[Set]] ( P, V, Receiver )
        9. 7.2.4.9 [[Delete]] ( P )
        10. 7.2.4.10 [[OwnPropertyKeys]] ( )
      5. 7.2.5 History 接口
      6. 7.2.6 导航 API
        1. 7.2.6.1 简介
        2. 7.2.6.2 Navigation 接口
        3. 7.2.6.3 核心基础设施
        4. 7.2.6.4 初始化和更新条目列表
        5. 7.2.6.5 NavigationHistoryEntry 接口
        6. 7.2.6.6 历史条目列表
        7. 7.2.6.7 启动导航
        8. 7.2.6.8 持续导航跟踪
        9. 7.2.6.9 NavigationActivation 接口
        10. 7.2.6.10 navigate 事件
          1. 7.2.6.10.1 NavigateEvent 接口
          2. 7.2.6.10.2 NavigationDestination 接口
          3. 7.2.6.10.3 触发事件
          4. 7.2.6.10.4 滚动和焦点行为
      7. 7.2.7 事件接口
        1. 7.2.7.1 NavigationCurrentEntryChangeEvent 接口
        2. 7.2.7.2 PopStateEvent 接口
        3. 7.2.7.3 HashChangeEvent 接口
        4. 7.2.7.4 PageSwapEvent 接口
        5. 7.2.7.5 PageRevealEvent 接口
        6. 7.2.7.6 PageTransitionEvent 接口
        7. 7.2.7.7 BeforeUnloadEvent 接口
      8. 7.2.8 NotRestoredReasons 接口

7.2.1 WindowWindowProxyLocation 对象的安全基础设施

尽管通常无法跨访问对象,但如果 Web 平台没有一些 Web 依赖的遗留例外情况,它就不会忠于自身。

本节使用 JavaScript 规范中的术语和排版约定。[JAVASCRIPT]

7.2.1.1 与 IDL 的集成

当调用执行安全检查时,使用 platformObjectidentifiertype,执行以下步骤

  1. 如果 platformObject 不是 WindowLocation 对象,则返回。

  2. 对于 CrossOriginProperties(platformObject) 的每个 e

    1. 如果 SameValue(e.[[Property]], identifier) 为真,则

      1. 如果 type 为“method”且 e 没有 [[NeedsGet]] 或 [[NeedsSet]],则返回。

      2. 否则,如果 type 为“getter”且 e.[[NeedsGet]] 为真,则返回。

      3. 否则,如果 type 为“setter”且 e.[[NeedsSet]] 为真,则返回。

  3. 如果 IsPlatformObjectSameOrigin(platformObject) 为假,则抛出一个SecurityError DOMException

7.2.1.2 共享内部槽位:[[CrossOriginPropertyDescriptorMap]]

WindowLocation 对象都具有一个 [[CrossOriginPropertyDescriptorMap]] 内部槽位,其值最初为空映射。

currentGlobal 检查来自 objectGlobalWindowLocation 对象时,[[CrossOriginPropertyDescriptorMap]] 内部槽位包含一个映射,其键为 (currentGlobalobjectGlobalpropertyKey) 元组,值为属性描述符,作为脚本可见性的备忘录。它由 CrossOriginGetOwnPropertyHelper 延迟填充,该操作在将来的查找中会查询它。

当没有任何内容持有对值的任何部分的引用时,用户代理应允许映射中保存的值与其对应的键一起被垃圾回收。也就是说,只要垃圾回收不可观察即可。

例如,使用 const href = Object.getOwnPropertyDescriptor(crossOriginLocation, "href").set,映射中的值及其对应的键无法被垃圾回收,因为这将是可观察的。

用户代理可能有一个优化,即当设置document.domain 时,它们会从映射中删除键值对。这不是可观察的,因为document.domain 无法重新访问早期值。

例如,在 www.example.com 上将document.domain 设置为“example.com”意味着用户代理可以从映射中删除所有键值对,其中键的一部分是 www.example.com,因为这永远不可能再成为的一部分,因此永远无法从映射中检索对应的值。

7.2.1.3 共享抽象操作
7.2.1.3.1 CrossOriginProperties ( O )
  1. 断言OLocationWindow 对象。

  2. 如果 OLocation 对象,则返回 « { [[Property]]: "href", [[NeedsGet]]: false, [[NeedsSet]]: true }, { [[Property]]: "replace" } »。

  3. 返回 « { [[Property]]: "window", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "self", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "location", [[NeedsGet]]: true, [[NeedsSet]]: true }, { [[Property]]: "close" }, { [[Property]]: "closed", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "focus" }, { [[Property]]: "blur" }, { [[Property]]: "frames", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "length", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "top", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "opener", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "parent", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "postMessage" } »。

此抽象操作不返回完成记录

索引属性不需要在此算法中进行安全列表,因为它们由 WindowProxy 对象直接处理。

如果 JavaScript 属性名称 P 为“window”、“self”、“location”、“close”、“closed”、“focus”、“blur”、“frames”、“length”、“top”、“opener”、“parent”、“postMessage”或数组索引属性名称,则它是 跨源可访问的窗口属性名称

7.2.1.3.2 CrossOriginPropertyFallback ( P )
  1. 如果 P 为“then”、“%Symbol.toStringTag%”、“%Symbol.hasInstance%”或“%Symbol.isConcatSpreadable%”,则返回 PropertyDescriptor{ [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

  2. 抛出一个SecurityError DOMException

7.2.1.3.3 IsPlatformObjectSameOrigin ( O )
  1. 如果当前设置对象O相关设置对象同源域,则返回true,否则返回false。

此抽象操作不返回完成记录

这里的当前设置对象大致对应于“调用者”,因为此检查发生在执行上下文在问题中的getter/setter/方法到达JavaScript执行上下文栈之前。例如,在代码w.document中,此步骤在document getter作为wWindowProxy[[Get]]算法的一部分被访问之前被调用。

7.2.1.3.4 CrossOriginGetOwnPropertyHelper ( O, P )

如果此抽象操作返回undefined且没有自定义行为,则调用者需要抛出一个"SecurityError" DOMException。在实践中,这由调用者调用CrossOriginPropertyFallback来处理。

  1. crossOriginKey为一个由当前设置对象O相关设置对象P组成的元组。

  2. 对于CrossOriginProperties(O)的每个e

    1. 如果SameValue(e.[[Property]], P)为true,则

      1. 如果O[[CrossOriginPropertyDescriptorMap]]内部槽包含一个键为crossOriginKey的条目,则返回该条目的值。

      2. originalDescOrdinaryGetOwnProperty(O, P)。

      3. crossOriginDesc为undefined。

      4. 如果e.[[NeedsGet]]和e.[[NeedsSet]]不存在,则

        1. valueoriginalDesc.[[Value]]。

        2. 如果IsCallable(value)为true,则将value设置为一个匿名内置函数,该函数在当前领域中创建,执行与对象O上IDL操作P相同的步骤。

        3. crossOriginDesc设置为PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }。

      5. 否则

        1. crossOriginGet为undefined。

        2. 如果e.[[NeedsGet]]为true,则将crossOriginGet设置为一个匿名内置函数,该函数在当前领域中创建,执行与对象O上IDL属性P的getter相同的步骤。

        3. crossOriginSet为undefined。

        4. 如果e.[[NeedsSet]]为true,则将crossOriginSet设置为一个匿名内置函数,该函数在当前领域中创建,执行与对象O上IDL属性P的setter相同的步骤。

        5. crossOriginDesc设置为PropertyDescriptor{ [[Get]]: crossOriginGet, [[Set]]: crossOriginSet, [[Enumerable]]: false, [[Configurable]]: true }。

      6. O[[CrossOriginPropertyDescriptorMap]]内部槽的值中创建一个条目,键为crossOriginKey,值为crossOriginDesc

      7. 返回crossOriginDesc

  3. 返回undefined。

此抽象操作不返回完成记录

这里生成的属性描述符可配置的原因是为了保持JavaScript规范所需的基本内部方法的不变性。特别是,由于属性的值可能会因导航而发生变化,因此要求该属性可配置。(但是,请参阅tc39/ecma262 issue #672以及本规范其他地方对此的引用,了解我们无法保持这些不变性的情况,以确保与现有Web内容的兼容性。)[JAVASCRIPT]

尽管这与同源行为不匹配,但属性描述符不可枚举的原因是为了与现有Web内容保持兼容。有关详细信息,请参阅issue #3183

7.2.1.3.5 CrossOriginGet ( O, P, Receiver )
  1. desc为?O.[[GetOwnProperty]](P)。

  2. 断言desc不为undefined。

  3. 如果IsDataDescriptor(desc)为true,则返回desc.[[Value]]。

  4. 断言IsAccessorDescriptor(desc)为true。

  5. getterdesc.[[Get]]。

  6. 如果getter为undefined,则抛出一个"SecurityError" DOMException

  7. 返回?Call(getter, Receiver)。

7.2.1.3.6 CrossOriginSet ( O, P, V, Receiver )
  1. desc为?O.[[GetOwnProperty]](P)。

  2. 断言desc不为undefined。

  3. 如果desc.[[Set]]存在且其值不为undefined,则

    1. 执行?Call(setter, Receiver, « V »)。

    2. 返回true。

  4. 抛出一个"SecurityError" DOMException

7.2.1.3.7 CrossOriginOwnPropertyKeys ( O )
  1. keys为一个新的空列表

  2. 对于CrossOriginProperties(O)的每个e追加e.[[Property]]到keys

  3. 返回keys和« "then", %Symbol.toStringTag%, %Symbol.hasInstance%, %Symbol.isConcatSpreadable% »的连接。

此抽象操作不返回完成记录

7.2.2 Window 对象

Window

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
[Global=Window,
 Exposed=Window,
 LegacyUnenumerableNamedProperties]
interface Window : EventTarget {
  // the current browsing context
  [LegacyUnforgeable] readonly attribute WindowProxy window;
  [Replaceable] readonly attribute WindowProxy self;
  [LegacyUnforgeable] readonly attribute Document document;
  attribute DOMString name; 
  [PutForwards=href, LegacyUnforgeable] readonly attribute Location location;
  readonly attribute History history;
  readonly attribute Navigation navigation;
  readonly attribute CustomElementRegistry customElements;
  [Replaceable] readonly attribute BarProp locationbar;
  [Replaceable] readonly attribute BarProp menubar;
  [Replaceable] readonly attribute BarProp personalbar;
  [Replaceable] readonly attribute BarProp scrollbars;
  [Replaceable] readonly attribute BarProp statusbar;
  [Replaceable] readonly attribute BarProp toolbar;
  attribute DOMString status;
  undefined close();
  readonly attribute boolean closed;
  undefined stop();
  undefined focus();
  undefined blur();

  // other browsing contexts
  [Replaceable] readonly attribute WindowProxy frames;
  [Replaceable] readonly attribute unsigned long length;
  [LegacyUnforgeable] readonly attribute WindowProxy? top;
  attribute any opener;
  [Replaceable] readonly attribute WindowProxy? parent;
  readonly attribute Element? frameElement;
  WindowProxy? open(optional USVString url = "", optional DOMString target = "_blank", optional [LegacyNullToEmptyString] DOMString features = "");

  // Since this is the global object, the IDL named getter adds a NamedPropertiesObject exotic
  // object on the prototype chain. Indeed, this does not make the global object an exotic object.
  // Indexed access is taken care of by the WindowProxy exotic object.
  getter object (DOMString name);

  // the user agent
  readonly attribute Navigator navigator;
  [Replaceable] readonly attribute Navigator clientInformation; // legacy alias of .navigator
  readonly attribute boolean originAgentCluster;

  // user prompts
  undefined alert();
  undefined alert(DOMString message);
  boolean confirm(optional DOMString message = "");
  DOMString? prompt(optional DOMString message = "", optional DOMString default = "");
  undefined print();

  undefined postMessage(any message, USVString targetOrigin, optional sequence<object> transfer = []);
  undefined postMessage(any message, optional WindowPostMessageOptions options = {});

  // also has obsolete members
};
Window includes GlobalEventHandlers;
Window includes WindowEventHandlers;

dictionary WindowPostMessageOptions : StructuredSerializeOptions {
  USVString targetOrigin = "/";
};
window.window

Window/window

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
window.frames

Window/frames

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
window.self

Window/self

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

这些属性都返回window

window.document

Window/document

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回与window关联的Document

document.defaultView

Document/defaultView

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

Window对象有一个关联的Document,它是一个Document对象。它在创建Window对象时设置,并且仅在从初始about:blankDocument进行导航期间更改。

Window浏览上下文是其关联的Document浏览上下文它要么为null,要么为浏览上下文

一个窗口可导航对象是那个可导航对象,其活动文档是该窗口关联的文档,或者如果不存在这样的可导航对象则为null。

windowframesself获取器步骤是返回this相关领域.[[GlobalEnv]].[[GlobalThisValue]]。

document获取器步骤是返回this关联的文档

窗口对象关联的文档对象只会在一种情况下发生变化:当导航算法为在浏览上下文中加载的第一个页面创建一个新的文档对象时。在这种特定情况下,初始about:blank页面的窗口对象会被重用,并获得一个新的文档对象。

defaultView获取器步骤如下:

  1. 如果this浏览上下文为null,则返回null。

  2. 返回this浏览上下文窗口代理对象。


HTML文档

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

出于历史原因,窗口对象还必须具有一个名为HTMLDocument的可写、可配置、不可枚举的属性,其值为文档接口对象

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

窗口/open

所有当前引擎都支持。

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

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

"noopener"
"noreferrer"

这些行为等同于超链接上的noopenernoreferrer链接类型。

"popup"

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

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

窗口/name

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回窗口的名称。

可以设置,以更改名称。

window.close()

窗口/close

所有当前引擎都支持。

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

关闭窗口。

window.closed

窗口/closed

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

window.stop()

窗口/stop

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)14+Internet Explorer不支持
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

取消文档加载。

给定字符串url、字符串target和字符串features窗口打开步骤如下:

  1. 如果事件循环终止嵌套级别不为零,则返回null。

  2. sourceDocument入口全局对象关联的文档

  3. 如果target为空字符串,则将target设置为"_blank"。

  4. tokenizedFeatures标记化features的结果。

  5. noopenernoreferrer为false。

  6. 如果tokenizedFeatures["noopener"]存在,则:

    1. noopener设置为tokenizedFeatures["noopener"]解析为布尔型特性的结果。

    2. 移除tokenizedFeatures["noopener"]。

  7. 如果tokenizedFeatures["noreferrer"]存在,则:

    1. noreferrer设置为tokenizedFeatures["noreferrer"]解析为布尔型特性的结果。

    2. 移除tokenizedFeatures["noreferrer"]。

  8. referrerPolicy为空字符串。

  9. 如果noreferrer为true,则将noopener设置为true,并将referrerPolicy设置为"no-referrer"。

  10. targetNavigablewindowType为应用选择可导航对象的规则的结果,给定targetsourceDocument节点可导航对象noopener

    如果存在支持通过控制点击链接在新标签页中打开它的用户代理,并且用户控制点击了一个其onclick处理程序使用window.open()API在iframe元素中打开页面的元素,用户代理可以覆盖目标浏览上下文的选取,改为将目标设置为一个新标签页。

  11. 如果targetNavigable为null,则返回null。

  12. 如果windowType为"new and unrestricted"或"new with no opener",则:

    1. targetNavigable活动浏览上下文is popup设置为检查是否请求了弹出窗口的结果,给定tokenizedFeatures

    2. 设置浏览上下文特性,针对targetNavigable活动浏览上下文,给定tokenizedFeatures[CSSOMVIEW]

    3. urlRecordURL记录about:blank

    4. 如果url不是空字符串,则将urlRecord设置为编码解析URL的结果,给定url,相对于入口设置对象

    5. 如果urlRecord为失败,则抛出一个"SyntaxError"DOMException

    6. 如果urlRecord匹配about:blank,则执行URL和历史记录更新步骤,给定targetNavigable活动文档urlRecord

      这在url类似于about:blank?foo的情况下是必要的。如果url只是简单的about:blank,则此操作不会执行任何操作。

    7. 否则,导航targetNavigableurlRecord,使用sourceDocument,其中referrerPolicy设置为referrerPolicy,并且exceptionsEnabled设置为true。

  13. 否则

    1. 如果url不是空字符串,则:

      1. urlRecord编码解析URLurl的结果,相对于入口设置对象

      2. 如果urlRecord为失败,则抛出一个"SyntaxError"DOMException

      3. 导航targetNavigableurlRecord,使用sourceDocument,其中referrerPolicy设置为referrerPolicy,并且exceptionsEnabled设置为true。

    2. 如果noopener为false,则将targetNavigable活动浏览上下文打开者浏览上下文设置为sourceDocument浏览上下文

  14. 如果noopener为true或windowType为"new with no opener",则返回null。

  15. 返回targetNavigable活动窗口代理

open(url, target, features) 方法的步骤是使用 urltargetfeatures 运行 窗口打开步骤

该方法提供了一种机制,用于 导航 现有的 浏览上下文 或打开并导航 辅助浏览上下文


features 参数进行标记化

  1. tokenizedFeatures 为一个新的 有序映射

  2. position 指向 features 的第一个代码点。

  3. position 未超过 features 的末尾时

    1. name 为空字符串。

    2. value 为空字符串。

    3. 收集一系列代码点,这些代码点是给定 positionfeatures 中的 特征分隔符。这会跳过名称之前的引导分隔符。

    4. 收集一系列代码点,这些代码点不是给定 positionfeatures 中的 特征分隔符。将 name 设置为收集到的字符,转换为 ASCII 小写

    5. name 设置为 规范化特征名称 name 的结果。

    6. position 未超过 features 的末尾且 featuresposition 处的代码点不是 U+003D (=) 时

      1. 如果 featuresposition 处的代码点是 U+002C (,),或者它不是 特征分隔符,则 跳出循环

      2. position 前进 1。

      这会跳到第一个 U+003D (=),但不会跳过 U+002C (,) 或非分隔符。

    7. 如果 featuresposition 处的代码点是 特征分隔符

      1. position 未超过 features 的末尾且 featuresposition 处的代码点是 特征分隔符

        1. 如果 featuresposition 处的代码点是 U+002C (,),则 跳出循环

        2. position 前进 1。

        这会跳到第一个非分隔符,但不会跳过 U+002C (,)。

      2. 收集一系列代码点,这些代码点不是给定 positionfeatures 中的 特征分隔符 代码点。将 value 设置为收集到的代码点,转换为 ASCII 小写

    8. 如果 name 不是空字符串,则将 tokenizedFeatures[name] 设置为 value

  4. 返回 tokenizedFeatures

检查窗口特征是否已设置,给定 tokenizedFeaturesfeatureNamedefaultValue

  1. 如果 tokenizedFeatures[featureName] 存在,则返回 tokenizedFeatures[featureName] 解析为布尔特征 的结果。

  2. 返回 defaultValue

检查是否请求了弹出窗口,给定 tokenizedFeatures

  1. 如果 tokenizedFeatures 为空,则返回 false。

  2. 如果 tokenizedFeatures["popup"] 存在,则返回 tokenizedFeatures["popup"] 解析为布尔特征 的结果。

  3. location检查窗口特征是否已设置 的结果,给定 tokenizedFeatures、"location" 和 false。

  4. toolbar检查窗口特征是否已设置 的结果,给定 tokenizedFeatures、"toolbar" 和 false。

  5. 如果 locationtoolbar 都为 false,则返回 true。

  6. menubar检查窗口特征是否已设置 的结果,给定 tokenizedFeatures、"menubar" 和 false。

  7. 如果 menubar 为 false,则返回 true。

  8. resizable检查窗口特征是否已设置 的结果,给定 tokenizedFeatures、"resizable" 和 true。

  9. 如果 resizable 为 false,则返回 true。

  10. scrollbars检查窗口特征是否已设置 的结果,给定 tokenizedFeatures、"scrollbars" 和 false。

  11. 如果 scrollbars 为 false,则返回 true。

  12. status检查窗口特征是否已设置 的结果,给定 tokenizedFeatures、"status" 和 false。

  13. 如果 status 为 false,则返回 true。

  14. 返回 false。

如果代码点是 ASCII 空格、U+003D (=) 或 U+002C (,),则该代码点为 特征分隔符

出于遗留原因,某些特征名称有一些别名。要 规范化特征名称 name,请根据 name 进行切换

"screenx"
返回 "left"。
"screeny"
返回 "top"。
"innerwidth"
返回 "width"。
"innerheight"
返回 "height"。
其他任何内容
返回 name

解析布尔特征,给定字符串 value

  1. 如果 value 为空字符串,则返回 true。

  2. 如果 value "yes",则返回 true。

  3. 如果 value "true",则返回 true。

  4. parsedvalue 解析为整数 的结果。

  5. 如果 parsed 为错误,则将其设置为 0。

  6. 如果 parsed 为 0,则返回 false,否则返回 true。


name 获取器的步骤是

  1. 如果 this可导航对象 为 null,则返回空字符串。

  2. 返回 this可导航对象目标名称

name 设置器的步骤是

  1. 如果 this可导航对象 为 null,则返回。

  2. this可导航对象活动会话历史条目文档状态可导航目标名称 设置为给定值。

当可导航对象 导航 到另一个 时,名称 将重置


close() 方法的步骤是

  1. thisTraversablethis可导航对象

  2. 如果 thisTraversable 不是 顶级可遍历对象,则返回。

  3. 如果 thisTraversable正在关闭 为 true,则返回。

  4. browsingContextthisTraversable活动浏览上下文

  5. sourceSnapshotParams 为给定 thisTraversable活动文档快照源快照参数 的结果。

  6. 如果以下所有条件都为真

    1. thisTraversable正在关闭 设置为 true。

    2. DOM 操作任务源关闭 thisTraversable 排队一个任务

如果一个可导航对象活动浏览上下文是由脚本创建的(而不是由用户操作创建的)辅助浏览上下文,或者它是一个顶级可遍历对象,且其会话历史记录条目大小为 1,则称该可导航对象脚本可关闭的

closed 获取器的步骤是:如果当前对象浏览上下文为 null 或其正在关闭为 true,则返回 true;否则返回 false。

stop() 方法的步骤如下:

  1. 如果当前对象可导航对象为 null,则返回。

  2. 停止加载当前对象可导航对象停止加载

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

Window/length

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

window[index]

返回对应于指定文档树子可导航对象WindowProxy

length 获取器的步骤是:返回当前对象关联的 Document文档树子可导航对象大小

文档树子可导航对象的索引访问是通过WindowProxy 对象的[[GetOwnProperty]] 内部方法定义的。

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

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

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

Window 对象 window文档树子可导航对象目标名称属性集 是运行以下步骤的结果:

  1. childrenwindow关联的 Document文档树子可导航对象

  2. firstNamedChildren 为一个空的有序集合

  3. 对于 children 中的每个 navigable 进行迭代

    1. namenavigable目标名称

    2. 如果 name 为空字符串,则继续

    3. 如果 firstNamedChildren 包含一个可导航对象,其目标名称name,则继续

    4. navigable 追加firstNamedChildren

  4. names 为一个空的有序集合

  5. 对于 firstNamedChildren 中的每个 navigable 进行迭代

    1. namenavigable目标名称

    2. 如果 navigable活动文档window相关设置对象同源,则将 name 追加names

  6. 返回 names

这两个单独的迭代意味着,在以下示例中,托管在 https://example.org/ 上,假设 https://elsewhere.example/window.name 设置为 "spices",在所有内容加载完成后评估 window.spices 将产生未定义。

<iframe src=https://elsewhere.example.com/></iframe>
<iframe name=spices></iframe>

Window 对象支持命名属性。在任何时刻,Window 对象 window支持的属性名称由以下内容组成,根据提供它们的元素的树序,忽略后面的重复项:

确定 Window 对象 window 中的命名属性 name 的值,用户代理必须使用以下步骤返回获得的值:

  1. objectswindow 中名称为 name命名对象的列表。

    至少会存在一个这样的对象,因为否则算法将不会被Web IDL 调用

  2. 如果 objects 包含一个可导航对象,则:

    1. containerwindow关联的 Document后代中第一个可导航容器,其内容可导航对象位于 objects 中。

    2. 返回 container内容可导航对象活动 WindowProxy

  3. 否则,如果 objects 只有一个元素,则返回该元素。

  4. 否则,返回一个以 window关联的 Document为根的HTMLCollection,其过滤器仅匹配名称为 namewindow命名对象。(根据定义,这些都将是元素。)

对于上述算法的目的,Window 对象 window 中名称为 name命名对象 由以下内容组成:

由于 Window 接口具有 [Global] 扩展属性,因此其命名属性遵循 命名属性对象 而不是 传统平台对象 的规则。

window.top

Window/top

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回顶级可遍历对象的 WindowProxy

window.opener [ = value ]

Window/opener

所有当前引擎都支持。

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

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

如果没有打开程序浏览上下文或已将其设置为 null,则返回 null。

可以设置为 null。

window.parent

Window/parent

所有当前引擎都支持。

Firefox1+Safari1.3+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回父可导航对象的 WindowProxy

window.frameElement

Window/frameElement

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回可导航容器元素。

如果没有可导航容器元素或处于跨源情况下,则返回 null。

top 获取器的步骤如下

  1. 如果 this可导航对象 为 null,则返回 null。

  2. 返回 this可导航对象顶级可遍历对象活动 WindowProxy

opener 获取器的步骤如下

  1. currentthis浏览上下文

  2. 如果 current 为 null,则返回 null。

  3. 如果 current打开程序浏览上下文 为 null,则返回 null。

  4. 返回 current打开程序浏览上下文WindowProxy 对象。

opener 设置器的步骤如下

  1. 如果给定值为 null 且 this浏览上下文 不为 null,则将 this浏览上下文打开程序浏览上下文 设置为 null。

  2. 如果给定值不为 null,则执行 ? DefinePropertyOrThrow(this,"opener",{ [[Value]]: 给定值,[[Writable]]: true,[[Enumerable]]: true,[[Configurable]]: true })。

window.opener 设置为 null 会清除 打开程序浏览上下文 的引用。在实践中,这会阻止未来的脚本访问其 打开程序浏览上下文Window 对象。

默认情况下,脚本可以通过 window.opener 获取器访问其 打开程序浏览上下文Window 对象。例如,脚本可以设置 window.opener.location,从而导致 打开程序浏览上下文 进行导航。

parent 获取器的步骤如下

  1. navigablethis可导航对象

  2. 如果 navigable 为 null,则返回 null。

  3. 如果 navigable父级 不为 null,则将 navigable 设置为 navigable父级

  4. 返回 navigable活动 WindowProxy

frameElement 获取器的步骤如下

  1. currentthis节点可导航对象

  2. 如果 current 为 null,则返回 null。

  3. containercurrent容器

  4. 如果 container 为 null,则返回 null。

  5. 如果 container节点文档当前设置对象同源,则返回 null。

  6. 返回 container

以下是一个这些属性可能返回 null 的示例

<!DOCTYPE html>
<iframe></iframe>

<script>
"use strict";
const element = document.querySelector("iframe");
const iframeWindow = element.contentWindow;
element.remove();

console.assert(iframeWindow.top === null);
console.assert(iframeWindow.parent === null);
console.assert(iframeWindow.frameElement === null);
</script>

这里,当 element 从文档中移除时,与 iframeWindow 对应的 浏览上下文设置为 null

7.2.2.5 历史浏览器界面元素 API

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

出于隐私和互操作性的原因,这些属性现在返回的值表示 Window浏览上下文is popup 属性为 true 还是 false。

每个界面元素都由一个 BarProp 对象表示

BarProp

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
[Exposed=Window]
interface BarProp {
  readonly attribute boolean visible;
};
window.locationbar.visible

Window/locationbar

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?
window.menubar.visible

Window/menubar

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?
window.personalbar.visible

Window/personalbar

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
window.scrollbars.visible

Window/scrollbars

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
window.statusbar.visible

Window/statusbar

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?
window.toolbar.visible

Window/toolbar

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?

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

BarProp/visible

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android?

visible 获取器的步骤如下

  1. browsingContextthis相关全局对象浏览上下文

  2. 如果 browsingContext 为 null,则返回 true。

  3. 返回 browsingContext顶级浏览上下文is popup 的反值。

每个 Window 对象都必须存在以下 BarProp 对象

位置栏 BarProp 对象
历史上表示包含显示浏览器位置栏的控件的用户界面元素。
菜单栏 BarProp 对象
历史上表示包含以菜单形式显示命令列表或某些类似界面概念的用户界面元素。
个人栏 BarProp 对象
历史上表示包含指向用户收藏页面的链接或某些类似界面概念的用户界面元素。
滚动条 BarProp 对象
历史上表示包含滚动机制或某些类似界面概念的用户界面元素。
状态栏 BarProp 对象

在历史上,表示一个用户界面元素,该元素通常位于文档的下方或之后(视用户的媒体而定),通常提供有关正在进行的网络活动的信息或用户指向设备当前指示的元素的信息。
工具栏 BarProp 对象
在历史上,表示一个用户界面元素,该元素通常位于文档的上方或之前(视用户的媒体而定),通常提供会话历史记录遍历控件(后退和前进按钮、重新加载按钮等)。

locationbar 属性必须返回位置栏 BarProp 对象

menubar 属性必须返回菜单栏 BarProp 对象

personalbar 属性必须返回个人栏 BarProp 对象

scrollbars 属性必须返回滚动条 BarProp 对象

statusbar 属性必须返回状态栏 BarProp 对象

toolbar 属性必须返回工具栏 BarProp 对象


出于历史原因,Window 对象上的 status 属性在获取时必须返回最后设置给它的字符串,在设置时必须将自身设置为新值。当创建 Window 对象时,该属性必须设置为空字符串。它不会执行任何其他操作。

7.2.2.6 Window 对象的脚本设置

设置窗口环境设置对象,给定一个URL creationURL、一个JavaScript 执行上下文 execution context、null 或一个环境 reservedEnvironment、一个URL topLevelCreationURL 和一个 topLevelOrigin,执行以下步骤

  1. realmexecution context 的 Realm 组件的值。

  2. windowrealm全局对象

  3. settings object 为一个新的环境设置对象,其算法定义如下

    领域执行上下文

    返回 execution context

    模块映射

    返回 window关联的 Document模块映射

    API 基本 URL

    返回 window关联的 Document 的当前基本 URL

    返回 window关联的 Document

    策略容器

    返回 window关联的 Document策略容器

    跨源隔离功能

    如果以下两个条件都成立,则返回 true,否则返回 false

    时间源

    返回 window关联的 Document加载计时信息导航开始时间

  4. 如果 reservedEnvironment 不为 null,则

    1. settings objectID 设置为 reservedEnvironmentID目标浏览上下文 设置为 reservedEnvironment目标浏览上下文,以及活动服务工作线程 设置为 reservedEnvironment活动服务工作线程

    2. reservedEnvironmentID 设置为空字符串。

      保留环境的标识被认为已完全转移到创建的环境设置对象。从这一点开始,无法通过环境ID 搜索保留环境。

  5. 否则,将 settings objectID 设置为一个新的唯一不透明字符串,settings object目标浏览上下文 设置为 null,以及 settings object活动服务工作线程 设置为 null。

  6. settings object创建 URL 设置为 creationURLsettings object顶级创建 URL 设置为 topLevelCreationURL,以及 settings object顶级源 设置为 topLevelOrigin

  7. realm 的 [[HostDefined]] 字段设置为 settings object

7.2.3 WindowProxy 奇异对象

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

WindowProxy 奇异对象必须使用普通内部方法,除非在下面明确指定了其他情况。

没有 WindowProxy 接口对象

每个 WindowProxy 对象都有一个 [[Window]] 内部槽,表示被包装的 Window 对象。

虽然 WindowProxy 被命名为“代理”,但它不像真正的代理那样在其目标的内部方法上执行多态分派,这是因为希望在 WindowProxyLocation 对象之间重用机制。只要 Window 对象保持为普通对象,这将是不可观察的,并且可以以任何一种方式实现。

7.2.3.1 [[GetPrototypeOf]] ()
  1. Wthis[[Window]] 内部槽的值。

  2. 如果 IsPlatformObjectSameOrigin(W) 为 true,则返回 ! OrdinaryGetPrototypeOf(W)。

  3. 返回 null。

7.2.3.2 [[SetPrototypeOf]] ( V )
  1. 返回 ! SetImmutablePrototype(this, V)。

7.2.3.3 [[IsExtensible]] ()
  1. 返回true。

7.2.3.4 [[PreventExtensions]] ()
  1. 返回 false。

7.2.3.5 [[GetOwnProperty]] ( P )
  1. Wthis[[Window]] 内部槽的值。

  2. 如果 P 是一个数组索引属性名称,则

    1. index 为 ! ToUint32(P)。

    2. childrenW关联的Document文档树子导航器

    3. value 为未定义。

    4. 如果index 小于children大小,则

      1. 排序children,按升序排列,如果navigableA容器navigableB容器 更早地插入到W关联的Document 中,则navigableA 小于navigableB

      2. value 设置为children[index] 的活动WindowProxy

    5. 如果value 为未定义,则

      1. 如果IsPlatformObjectSameOrigin(W) 为真,则返回未定义。

      2. 抛出一个SecurityError DOMException

    6. 返回PropertyDescriptor{ [[Value]]: value, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true }。

  3. 如果IsPlatformObjectSameOrigin(W) 为真,则返回 ! OrdinaryGetOwnProperty(W, P)。

    为了与现有的 Web 内容保持兼容性,这是对 JavaScript 规范的基本内部方法的不变式有意违反。有关更多信息,请参阅tc39/ecma262 issue #672[JAVASCRIPT]

  4. propertyCrossOriginGetOwnPropertyHelper(W, P)。

  5. 如果property 不为未定义,则返回property

  6. 如果property 为未定义且P 位于W文档树子导航器目标名称属性集 中,则

    1. value 为名称为PW命名对象活动WindowProxy

    2. 返回PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }。

      尽管这与同源行为不匹配,但属性描述符不可枚举的原因是为了与现有Web内容保持兼容。有关详细信息,请参阅issue #3183

  7. 返回 ? CrossOriginPropertyFallback(P)。

7.2.3.6 [[DefineOwnProperty]] ( P, Desc )
  1. Wthis[[Window]] 内部槽的值。

  2. 如果IsPlatformObjectSameOrigin(W) 为真,则

    1. 如果P数组索引属性名,则返回 false。

    2. 返回 ? OrdinaryDefineOwnProperty(W, P, Desc)。

      为了与现有的 Web 内容保持兼容性,这是对 JavaScript 规范的基本内部方法的不变式有意违反。有关更多信息,请参阅tc39/ecma262 issue #672[JAVASCRIPT]

  3. 抛出一个SecurityError DOMException

7.2.3.7 [[Get]] ( P, Receiver )
  1. Wthis[[Window]] 内部槽的值。

  2. 检查是否应报告两个浏览上下文的访问,给定当前全局对象浏览上下文W浏览上下文P当前设置对象

  3. 如果IsPlatformObjectSameOrigin(W) 为真,则返回 ? OrdinaryGet(this, P, Receiver)。

  4. 返回 ? CrossOriginGet(this, P, Receiver)。

this 而不是W 被传递,因为OrdinaryGetCrossOriginGet 将调用[[GetOwnProperty]] 内部方法。

7.2.3.8 [[Set]] ( P, V, Receiver )
  1. Wthis[[Window]] 内部槽的值。

  2. 检查是否应报告两个浏览上下文的访问,给定当前全局对象浏览上下文W浏览上下文P当前设置对象

  3. 如果IsPlatformObjectSameOrigin(W) 为真,则

    1. 如果P数组索引属性名,则返回 false。

    2. 返回 ? OrdinarySet(W, P, V, Receiver)。

  4. 返回 ? CrossOriginSet(this, P, V, Receiver)。

    this 而不是W 被传递,因为CrossOriginSet 将调用[[GetOwnProperty]] 内部方法。

7.2.3.9 [[Delete]] ( P )
  1. Wthis[[Window]] 内部槽的值。

  2. 如果IsPlatformObjectSameOrigin(W) 为真,则

    1. 如果P数组索引属性名,则

      1. desc 为 ! this.[[GetOwnProperty]](P)。

      2. 如果desc 为未定义,则返回 true。

      3. 返回 false。

    2. 返回 ? OrdinaryDelete(W, P)。

  3. 抛出一个SecurityError DOMException

7.2.3.10 [[OwnPropertyKeys]] ( )
  1. Wthis[[Window]] 内部槽的值。

  2. maxPropertiesW关联的Document文档树子导航器大小

  3. keys范围 0 到maxProperties,不包括maxProperties

  4. 如果IsPlatformObjectSameOrigin(W) 为真,则返回keysOrdinaryOwnPropertyKeys(W) 的连接。

  5. 返回keys 和 ! CrossOriginOwnPropertyKeys(W) 的连接。

7.2.4 Location 接口

Document/location

所有当前引擎都支持。

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

Location

所有当前引擎都支持。

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

Window/location

所有当前引擎都支持。

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

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

通过 IDL、创建后调用 JavaScript 内部方法以及覆盖的 JavaScript 内部方法的混合方式定义Location 外来对象。加上其可怕的安全策略,在实现此异常情况时,请格外小心。

要创建一个Location 对象,请执行以下步骤

  1. location 为一个新的Location 平台对象

  2. valueOflocation相关领域.[[Intrinsics]].[[%Object.prototype.valueOf%]]。

  3. 执行 ! location.[[DefineOwnProperty]]("valueOf", { [[Value]]: valueOf, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。

  4. 执行 ! location.[[DefineOwnProperty]](%Symbol.toPrimitive%, { [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。

  5. location[[DefaultProperties]] 内部槽的值设置为location.[[OwnPropertyKeys]]()。

  6. 返回location

添加valueOf%Symbol.toPrimitive% 自有数据属性,以及Location 的所有 IDL 属性都标记为[LegacyUnforgeable],这是由查询Location 接口或将其字符串化的旧版代码所需的,以确定文档 URL,然后以安全敏感的方式使用它。特别是,valueOf%Symbol.toPrimitive%[LegacyUnforgeable] 字符串化缓解措施可确保诸如foo[location] = barlocation + "" 之类的代码不会被误导。

document.location [ = value ]
windowlocation [ = value ]

返回一个表示当前页面位置的 Location 对象。

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

Document 对象的 location 获取器步骤是,如果 this完全激活的,则返回 相关全局对象Location 对象;否则返回 null。

Window 对象的 location 获取器步骤是,返回 thisLocation 对象。

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

[Exposed=Window]
interface Location { // but see also additional creation steps and overridden internal methods
  [LegacyUnforgeable] stringifier attribute USVString href;
  [LegacyUnforgeable] readonly attribute USVString origin;
  [LegacyUnforgeable] attribute USVString protocol;
  [LegacyUnforgeable] attribute USVString host;
  [LegacyUnforgeable] attribute USVString hostname;
  [LegacyUnforgeable] attribute USVString port;
  [LegacyUnforgeable] attribute USVString pathname;
  [LegacyUnforgeable] attribute USVString search;
  [LegacyUnforgeable] attribute USVString hash;

  [LegacyUnforgeable] undefined assign(USVString url);
  [LegacyUnforgeable] undefined replace(USVString url);
  [LegacyUnforgeable] undefined reload();

  [LegacyUnforgeable, SameObject] readonly attribute DOMStringList ancestorOrigins;
};
location.toString()
location.href

Location/href

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Location/toString

所有当前引擎都支持。

Firefox22+Safari1+Chrome52+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回 Location 对象的 URL。

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

location.origin

Location/origin

所有当前引擎都支持。

Firefox21+Safari5.1+Chrome8+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android?

返回 Location 对象的 URL 的来源。

location.protocol

Location/protocol

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的方案。

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

location.host

Location/host

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

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

location.hostname

Location/hostname

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的主机。

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

location.port

Location/port

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的端口。

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

location.pathname

Location/pathname

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的路径。

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

location.search

Location/search

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

可以设置该属性,以使用更改后的查询字符串导航到相同的 URL(忽略前导“?”)。

location.hash

Location/hash

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

可以设置该属性,以使用更改后的片段标识符导航到相同的 URL(忽略前导“#”)。

location.assign(url)

Location/assign

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

导航到给定的 URL。

location.replace(url)

Location/replace

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

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

location.reload()

Location/reload

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

重新加载当前页面。

location.ancestorOrigins

Location/ancestorOrigins

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

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

一个 Location 对象有一个关联的 相关 Document,如果此 Location 对象的 相关全局对象浏览上下文 不为 null,则该关联的 Document 为其 相关全局对象浏览上下文活动文档;否则为 null。

一个 Location 对象有一个关联的 url,如果此 Location 对象的 相关 Document 不为 null,则该关联的 url 为此 Location 对象的 相关 DocumentURL;否则为 about:blank

一个 Location 对象有一个关联的 祖先来源列表。当创建 Location 对象时,其 祖先来源列表 必须设置为一个 DOMStringList 对象,其关联的列表是以下步骤将产生的字符串 列表

  1. output 为一个新的字符串 列表

  2. currentLocation 对象的 相关 Document

  3. current容器文档 不为 null 时

    1. current 设置为 current容器文档

    2. current来源序列化 追加到 output

  4. 返回 output

Location 对象 location 导航URL url,可以选择提供一个 NavigationHistoryBehavior historyHandling(默认为 "auto")

  1. navigablelocation相关全局对象可导航对象

  2. sourceDocument当前全局对象关联的 Document

  3. 如果 location相关 Document 尚未 完全加载,并且 当前全局对象 没有 瞬时激活,则将 historyHandling 设置为 "replace"。

  4. 使用 sourceDocumentnavigable 导航到 url,其中 exceptionsEnabled 设置为 true,并且 historyHandling 设置为 historyHandling

href 获取器步骤如下

  1. 如果 this相关 Document 不为 null,并且其 来源入口设置对象来源 不是 同源,则抛出一个 "SecurityError" DOMException

  2. 返回 thisurl序列化后的结果。

href 设置器的步骤如下

  1. 如果 this相关 Document 为 null,则返回。

  2. url 为根据给定值,相对于 入口设置对象 编码解析 URL 的结果。

  3. 如果 url 为失败,则抛出一个 "SyntaxError" DOMException

  4. Location 对象导航 thisurl

href 设置器有意不进行安全检查。

origin 获取器的步骤如下

  1. 如果 this相关 Document 不为 null 且其 origin入口设置对象origin 不属于同源域,则抛出一个 "SecurityError" DOMException

  2. 返回 thisurlorigin序列化 结果。

protocol 获取器的步骤如下

  1. 如果 this相关 Document 不为 null 且其 origin入口设置对象origin 不属于同源域,则抛出一个 "SecurityError" DOMException

  2. 返回 thisurlscheme,后跟 ":"。

protocol 设置器的步骤如下

  1. 如果 this相关 Document 为 null,则返回。

  2. 如果 this相关 Documentorigin入口设置对象origin 不属于同源域,则抛出一个 "SecurityError" DOMException

  3. copyURLthisurl 的副本。

  4. possibleFailure基本 URL 解析 给定值(后跟 ":"),其中 copyURL 作为 urlscheme 起始状态 作为 状态覆盖 的结果。

    因为 URL 解析器会忽略多个连续的冒号,所以提供 "https:"(甚至 "https::::")的值与提供 "https" 的值相同。

  5. 如果 possibleFailure 为失败,则抛出一个 "SyntaxError" DOMException

  6. 如果 copyURLscheme 不是 HTTP(S) scheme,则终止这些步骤。

  7. Location 对象导航 thiscopyURL

host 获取器的步骤如下

  1. 如果 this相关 Document 不为 null 且其 origin入口设置对象origin 不属于同源域,则抛出一个 "SecurityError" DOMException

  2. urlthisurl

  3. 如果 urlhost 为 null,则返回空字符串。

  4. 如果 urlport 为 null,则返回 urlhost序列化后的结果。

  5. 返回 urlhost序列化后的结果,后跟 ":" 和 urlport序列化后的结果。

host 设置器的步骤如下

  1. 如果 this相关 Document 为 null,则返回。

  2. 如果 this相关 Documentorigin入口设置对象origin 不属于同源域,则抛出一个 "SecurityError" DOMException

  3. copyURLthisurl 的副本。

  4. 如果 copyURL不透明路径,则返回。

  5. 基本 URL 解析 给定值,其中 copyURL 作为 urlhost 状态 作为 状态覆盖

  6. Location 对象导航 thiscopyURL

hostname 获取器的步骤如下

  1. 如果 this相关 Document 不为 null 且其 origin入口设置对象origin 不属于同源域,则抛出一个 "SecurityError" DOMException

  2. 如果 thisurlhost 为 null,则返回空字符串。

  3. 返回 thisurlhost序列化后的结果。

hostname 设置器的步骤如下

  1. 如果this相关 Document 为空,则返回。

  2. 如果this相关 Document入口设置对象同源,则抛出SecurityErrorDOMException

  3. copyURLthisurl的副本。

  4. 如果copyURL具有不透明路径,则返回。

  5. 基本URL解析给定值,其中copyURL作为url主机名状态作为状态覆盖

  6. Location对象导航thiscopyURL

port获取器的步骤为

  1. 如果this相关 Document不为空,并且其入口设置对象同源,则抛出SecurityErrorDOMException

  2. 如果thisurl端口为空,则返回空字符串。

  3. 返回thisurl端口序列化后的结果。

port设置器的步骤为

  1. 如果this相关 Document为空,则返回。

  2. 如果this相关 Document入口设置对象同源,则抛出SecurityErrorDOMException

  3. copyURLthisurl的副本。

  4. 如果copyURL不能具有用户名/密码/端口,则返回。

  5. 如果给定值为空字符串,则将copyURL端口设置为null。

  6. 否则,基本URL解析给定值,其中copyURL作为url端口状态作为状态覆盖

  7. Location对象导航thiscopyURL

pathname获取器的步骤为

  1. 如果this相关 Document不为空,并且其入口设置对象同源,则抛出SecurityErrorDOMException

  2. 返回URL路径序列化Location对象的url的结果。

pathname设置器的步骤为

  1. 如果this相关 Document为空,则返回。

  2. 如果this相关 Document入口设置对象同源,则抛出SecurityErrorDOMException

  3. copyURLthisurl的副本。

  4. 如果copyURL具有不透明路径,则返回。

  5. copyURL路径设置为空列表。

  6. 基本URL解析给定值,其中copyURL作为url路径开始状态作为状态覆盖

  7. Location对象导航thiscopyURL

search获取器的步骤为

  1. 如果this相关 Document不为空,并且其入口设置对象同源,则抛出SecurityErrorDOMException

  2. 如果thisurl查询为空或null,则返回空字符串。

  3. 返回“?”,后跟thisurl查询

search设置器的步骤为

  1. 如果this相关 Document为空,则返回。

  2. 如果this相关 Document入口设置对象同源,则抛出SecurityErrorDOMException

  3. copyURLthisurl的副本。

  4. 如果给定值为空字符串,则将copyURL查询设置为null。

  5. 否则,执行以下子步骤

    1. input为给定值,如果存在,则移除其开头的单个“?”。

    2. copyURL查询设置为空字符串。

    3. 基本URL解析input,其中null,相关 Document文档字符编码copyURL作为url查询状态作为状态覆盖

  6. Location对象导航thiscopyURL

hash 属性的 getter 步骤如下:

  1. 如果 this相关 Document 不为 null,并且其 来源入口设置对象来源 不是 同源域,则抛出一个 "SecurityError" DOMException

  2. 如果 thisURL片段 为 null 或空字符串,则返回空字符串。

  3. 返回 "#",后跟 thisURL片段

hash 属性的 setter 步骤如下:

  1. 如果 this相关 Document 为 null,则返回。

  2. 如果 this相关 Document来源入口设置对象来源 不是 同源域,则抛出一个 "SecurityError" DOMException

  3. copyURLthisURL 的副本。

  4. input 为给定的值,如果该值以单个 "#" 开头,则将其移除。

  5. copyURL片段 设置为空字符串。

  6. 使用 copyURL 作为 URL片段状态 作为 状态覆盖,对 input 进行 基本 URL 解析

  7. 如果 copyURL片段 等于 thisURL片段,则返回。

    此回退对于与已部署内容的兼容性是必要的,这些内容 在滚动时冗余地设置 location.hash。它不适用于其他片段导航机制,例如 location.href setter 或 location.assign()

  8. this 导航到 copyURL,使用 Location 对象导航

aarea 元素的等效 API 不同,hash setter 不会对空字符串进行特殊处理,以保持与已部署脚本的兼容性。


assign(url) 方法的步骤如下:

  1. 如果 this相关 Document 为 null,则返回。

  2. 如果 this相关 Document来源入口设置对象来源 不是 同源域,则抛出一个 "SecurityError" DOMException

  3. urlRecord 为给定 url 相对于 入口设置对象URL 编码解析 结果。

  4. 如果 urlRecord 为失败,则抛出一个 "SyntaxError" DOMException

  5. this 导航到 urlRecord,使用 Location 对象导航

replace(url) 方法的步骤如下:

  1. 如果 this相关 Document 为 null,则返回。

  2. urlRecord 为给定 url 相对于 入口设置对象URL 编码解析 结果。

  3. 如果 urlRecord 为失败,则抛出一个 "SyntaxError" DOMException

  4. this 导航到 urlRecord,并使用 "replace",使用 Location 对象导航

replace() 方法有意不进行安全检查。

reload() 方法的步骤如下:

  1. documentthis相关 Document

  2. 如果 document 为 null,则返回。

  3. 如果 document来源入口设置对象来源 不是 同源域,则抛出一个 "SecurityError" DOMException

  4. 重新加载 document节点可导航对象,使用 重新加载


ancestorOrigins 属性的 getter 步骤如下:

  1. 如果 this相关 Document 为 null,则返回一个空的 列表

  2. 如果 this相关 Document来源入口设置对象来源 不是 同源域,则抛出一个 "SecurityError" DOMException

  3. 否则,返回 this祖先来源列表

ancestorOrigins 属性的工作细节仍然存在争议,可能会发生变化。有关更多信息,请参阅 问题 #1918


如前所述,Location 外来对象出于安全目的需要超出 IDL 的额外逻辑。Location 对象必须使用普通内部方法,除非下面明确指定了其他情况。

此外,每个 Location 对象都有一个 [[DefaultProperties]] 内部槽,表示其在创建时自己的属性。

7.2.4.1 [[GetPrototypeOf]] ( )
  1. 如果 IsPlatformObjectSameOrigin(this) 为 true,则返回 ! OrdinaryGetPrototypeOf(this)。

  2. 返回 null。

7.2.4.2 [[SetPrototypeOf]] ( V )
  1. 返回 ! SetImmutablePrototype(this, V)。

7.2.4.3 [[IsExtensible]] ( )
  1. 返回true。

7.2.4.4 [[PreventExtensions]] ( )
  1. 返回 false。

7.2.4.5 [[GetOwnProperty]] ( P )
  1. 如果 IsPlatformObjectSameOrigin(this) 为 true,则

    1. descOrdinaryGetOwnProperty(this, P)。

    2. 如果 this[[DefaultProperties]] 内部槽的值包含 P,则将 desc.[[Configurable]] 设置为 true。

    3. 返回 desc

  2. propertyCrossOriginGetOwnPropertyHelper(this, P)。

  3. 如果property 不为未定义,则返回property

  4. 返回 ? CrossOriginPropertyFallback(P)。

7.2.4.6 [[DefineOwnProperty]] ( P, Desc )
  1. 如果 IsPlatformObjectSameOrigin(this) 为 true,则

    1. 如果this[[DefaultProperties]]内部槽包含P,则返回 false。

    2. 返回 ? OrdinaryDefineOwnProperty(this, P, Desc).

  2. 抛出一个"SecurityError" DOMException

7.2.4.7 [[Get]] ( P, Receiver )
  1. 如果 IsPlatformObjectSameOrigin(this) 为 true,则返回 ? OrdinaryGet(this, P, Receiver).

  2. 返回 ? CrossOriginGet(this, P, Receiver).

7.2.4.8 [[Set]] ( P, V, Receiver )
  1. 如果 IsPlatformObjectSameOrigin(this) 为 true,则返回 ? OrdinarySet(this, P, V, Receiver).

  2. 返回 ? CrossOriginSet(this, P, V, Receiver).

7.2.4.9 [[Delete]] ( P )
  1. 如果 IsPlatformObjectSameOrigin(this) 为 true,则返回 ? OrdinaryDelete(this, P).

  2. 抛出一个"SecurityError" DOMException

7.2.4.10 [[OwnPropertyKeys]] ( )
  1. 如果 IsPlatformObjectSameOrigin(this) 为 true,则返回 OrdinaryOwnPropertyKeys(this)。

  2. 返回 CrossOriginOwnPropertyKeys(this)。

7.2.5 History 接口

历史记录

所有当前引擎都支持。

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

窗口/历史记录

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
enum ScrollRestoration { "auto", "manual" };

[Exposed=Window]
interface History {
  readonly attribute unsigned long length;
  attribute ScrollRestoration scrollRestoration;
  readonly attribute any state;
  undefined go(optional long delta = 0);
  undefined back();
  undefined forward();
  undefined pushState(any data, DOMString unused, optional USVString? url = null);
  undefined replaceState(any data, DOMString unused, optional USVString? url = null);
};
history.length

历史记录/长度

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

history.scrollRestoration

历史记录/scrollRestoration

所有当前引擎都支持。

Firefox46+Safari11+Chrome46+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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

history.scrollRestoration = value

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

history.state

历史记录/state

所有当前引擎都支持。

Firefox4+Safari6+Chrome19+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

history.go()

重新加载当前页面。

history.go(delta)

历史记录/go

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

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

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

history.back()

历史记录/back

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

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

history.forward()

历史记录/forward

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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

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

history.pushState(data, "")

历史记录/pushState

所有当前引擎都支持。

Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+

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

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

history.pushState(data, "", url)

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

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

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

history.replaceState(data, "")

历史记录/replaceState

所有当前引擎都支持。

Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+

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

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

history.replaceState(data, "", url)

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

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

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

一个Document有一个history 对象,一个History对象。

history获取器的步骤是返回this关联的Documenthistory 对象


每个History对象都有状态,最初为 null。

每个History对象都有一个长度,一个非负整数,最初为 0。

每个History对象都有一个索引,一个非负整数,最初为 0。

尽管索引没有直接公开,但可以通过在同步导航期间对长度的更改来推断。事实上,这就是它的用途。

length获取器的步骤是

  1. 如果this相关全局对象关联的Document不是完全活动状态,则抛出一个"SecurityError" DOMException

  2. 返回this长度

scrollRestoration获取器的步骤是

  1. 如果this相关全局对象关联的Document不是完全活动状态,则抛出一个"SecurityError" DOMException

  2. 返回this节点导航对象活动会话历史记录条目滚动恢复模式

scrollRestoration设置器的步骤是

  1. 如果this相关全局对象关联的Document不是完全激活的,则抛出一个"SecurityError" DOMException

  2. this节点可导航活动会话历史条目滚动恢复模式设置为给定值。

state 获取器的步骤如下

  1. 如果this相关全局对象关联的Document不是完全激活的,则抛出一个"SecurityError" DOMException

  2. 返回this状态

go(delta) 方法的步骤是根据给定的delta 进行增量遍历 this

back() 方法的步骤是根据给定的−1 进行增量遍历 this

forward() 方法的步骤是根据给定的+1 进行增量遍历 this

进行增量遍历一个History对象history,并给定一个整数delta

  1. documenthistory相关全局对象关联的Document

  2. 如果document不是完全激活的,则抛出一个"SecurityError" DOMException

  3. 如果delta为0,则重新加载document节点可导航,并返回。

  4. 根据增量遍历历史记录,给定document节点可导航可遍历导航delta,并将sourceDocument设置为document

pushState(data, unused, url) 方法的步骤是根据给定的thisdataurl和"push"运行共享的历史记录推送/替换状态步骤

replaceState(data, unused, url) 方法的步骤是根据给定的thisdataurl和"replace"运行共享的历史记录推送/替换状态步骤

给定一个History history、一个值data、一个标量值字符串-或-null url和一个历史记录处理行为 historyHandling共享的历史记录推送/替换状态步骤如下

  1. documenthistory的关联Document

  2. 如果document不是完全激活的,则抛出一个"SecurityError" DOMException

  3. 可以选择返回。(例如,用户代理可能会禁止对在计时器上调用的、或在不是响应明确用户操作触发的事件侦听器中调用的、或在快速连续调用时调用的这些方法的调用。)

  4. serializedDataStructuredSerializeForStorage(data)。重新抛出任何异常。

  5. newURLdocumentURL

  6. 如果url不是null或空字符串,则

    1. newURL设置为根据给定的url 编码解析URL的结果,相对于history相关设置对象

    2. 如果newURL为失败,则抛出一个"SecurityError" DOMException

    3. 如果document 无法将其URL重写newURL,则抛出一个"SecurityError" DOMException

    此处空字符串的特殊情况是历史遗留的,在比较诸如location.href = ""(对空字符串执行URL解析)与history.pushState(null, "", "")(绕过它)之类的代码时会导致不同的结果URL。

  7. navigationhistory相关全局对象导航API

  8. continuenavigation上触发push/replace/reload navigate 事件的结果,其中navigationType设置为historyHandlingisSameDocument设置为true,destinationURL设置为newURL,以及classicHistoryAPIState设置为serializedData

  9. 如果continue为false,则返回。

  10. 运行URL和历史记录更新步骤,给定documentnewURL,其中serializedData设置为serializedDatahistoryHandling设置为historyHandling

用户代理可能会限制每个页面添加到会话历史记录中的状态对象的数量。如果页面达到实现定义的限制,则用户代理必须在添加新条目后立即删除该Document对象的会话历史记录中第一个条目之后的条目。(因此,状态历史记录充当用于驱逐的FIFO缓冲区,但充当用于导航的LIFO缓冲区。)

一个Document document 可以将其URL重写为一个URL targetURL,如果以下算法返回true

  1. documentURLdocumentURL

  2. 如果targetURLdocumentURL在其方案用户名密码主机端口组件方面存在差异,则返回false。

  3. 如果targetURL方案HTTP(S)方案,则返回true。

    路径查询片段方面的差异对于http:https: URL是允许的。

  4. 如果targetURL方案为"file",则

    1. 如果targetURLdocumentURL在其路径组件方面存在差异,则返回false。

    2. 返回true。

    查询片段方面的差异对于file: URL是允许的。

  5. 如果targetURLdocumentURL在其路径组件或查询组件方面存在差异,则返回false。

    对于其他类型的URL,仅允许片段方面的差异。

  6. 返回true。

文档的URL目标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;
[Exposed=Window]
interface Navigation : EventTarget {
  sequence<NavigationHistoryEntry> entries();
  readonly attribute NavigationHistoryEntry? currentEntry;
  undefined updateCurrentEntry(NavigationUpdateCurrentEntryOptions options);
  readonly attribute NavigationTransition? transition;
  readonly attribute NavigationActivation? activation;

  readonly attribute boolean canGoBack;
  readonly attribute boolean canGoForward;

  NavigationResult navigate(USVString url, optional NavigationNavigateOptions options = {});
  NavigationResult reload(optional NavigationReloadOptions options = {});

  NavigationResult traverseTo(DOMString key, optional NavigationOptions options = {});
  NavigationResult back(optional NavigationOptions options = {});
  NavigationResult forward(optional NavigationOptions options = {});

  attribute EventHandler onnavigate;
  attribute EventHandler onnavigatesuccess;
  attribute EventHandler onnavigateerror;
  attribute EventHandler oncurrententrychange;
};

dictionary NavigationUpdateCurrentEntryOptions {
  required any state;
};

dictionary NavigationOptions {
  any info;
};

dictionary NavigationNavigateOptions : NavigationOptions {
  any state;
  NavigationHistoryBehavior history = "auto";
};

dictionary NavigationReloadOptions : NavigationOptions {
  any state;
};

dictionary NavigationResult {
  Promise<NavigationHistoryEntry> committed;
  Promise<NavigationHistoryEntry> finished;
};

enum NavigationHistoryBehavior {
  "auto",
  "push",
  "replace"
};

每个Window都有一个关联的导航API,它是一个Navigation对象。在创建Window对象时,其导航API必须设置为在Window对象的相关领域中创建的Navigation对象。

navigation getter 步骤是返回this导航API

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

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

每个Navigation都有一个关联的条目列表,一个NavigationHistoryEntry对象的列表,最初为空。

每个Navigation都有一个关联的当前条目索引,一个整数,最初为-1。

Navigation navigation当前条目是运行以下步骤的结果

  1. 如果navigation已禁用条目和事件,则返回null。

  2. 断言navigation当前条目索引不是-1。

  3. 返回navigation条目列表[navigation当前条目索引]。

如果以下步骤返回true,则Navigation navigation已禁用条目和事件

  1. documentnavigation相关全局对象关联的Document

  2. 如果document不是完全活动,则返回true。

  3. 如果document是初始about:blank为true,则返回true。

  4. 如果document不透明,则返回true。

  5. 返回 false。

获取导航API条目索引,需要一个在导航 navigation中的会话历史条目 she

  1. index为0。

  2. 对于navigation条目列表中的每个nhe

    1. 如果nhe会话历史条目等于she,则返回index

    2. index加1。

  3. 返回−1。


在整个导航API中使用的一个关键类型是NavigationType枚举

enum NavigationType {
 "push",
 "replace",
 "reload",
 "traverse"
};

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

"push"
对应于导航的调用,其中历史处理行为最终变为"push",或对应于history.pushState()
"replace"
对应于导航的调用,其中历史处理行为最终变为"replace",或对应于history.replaceState()
"reload"
对应于reload的调用。
"traverse"
对应于通过增量遍历历史记录的调用。

NavigationType枚举的值空间是规范内部历史处理行为类型的值空间的超集。此标准的几个部分利用了这种重叠,方法是将历史处理行为传递给期望NavigationType的算法。

7.2.6.4 初始化和更新条目列表

为新文档初始化导航API条目,需要给定一个导航 navigation,一个列表会话历史条目 newSHEs,以及一个会话历史条目 initialSHE

  1. 断言navigation条目列表为空

  2. 断言navigation当前条目索引为−1。

  3. 如果navigation已禁用条目和事件,则返回。

  4. 对于newSHEs中的每个newSHE

    1. newNHE为在navigation相关领域中创建的一个新的NavigationHistoryEntry

    2. newNHE会话历史条目设置为newSHE

    3. 追加newNHEnavigation条目列表

    newSHEs最初将来自获取导航API的会话历史条目,因此每个newSHE都将与initialSHE具有连续的相同

  5. navigation当前条目索引设置为initialSHEnavigation获取导航API条目索引的结果。

更新重新激活的导航API条目,需要给定一个导航 navigation,一个列表会话历史条目 newSHEs,以及一个会话历史条目 reactivatedSHE

  1. 如果navigation已禁用条目和事件,则返回。

  2. newNHEs为一个新的空列表

  3. oldNHEsnavigation条目列表克隆

  4. 对于newSHEs中的每个newSHE

    1. newNHE为null。

    2. 如果oldNHEs包含一个NavigationHistoryEntry matchingOldNHE,其会话历史条目newSHE,则

      1. newNHE设置为matchingOldNHE

      2. 移除matchingOldNHEoldNHEs

    3. 否则

      1. newNHE设置为在navigation相关领域中创建的一个新的NavigationHistoryEntry

      2. newNHE会话历史条目设置为newSHE

    4. 追加newNHEnewNHEs

    newSHEs最初将来自获取导航API的会话历史条目,因此每个newSHE都将与reactivatedSHE具有连续的相同

    在此循环结束时,oldNHEs中剩余的所有NavigationHistoryEntry都代表在Document处于bfcache期间已处置的会话历史条目

  5. navigation条目列表设置为newNHEs

  6. navigation当前条目索引设置为reactivatedSHEnavigation获取导航API条目索引的结果。

  7. navigation相关全局对象上,在导航和遍历任务源上排队一个全局任务,以运行以下步骤

    1. 对于oldNHEs中的每个disposedNHE

      1. 触发名为dispose的事件,目标为disposedNHE

    我们通过任务延迟这些步骤,以确保dispose事件将在pageshow事件之后触发。这确保了pageshow是页面在重新激活时收到的第一个事件。

    (但是,此算法的其余部分在pageshow事件触发之前运行。这确保了在任何pageshow事件处理程序期间,navigation.entries()navigation.currentEntry将具有正确更新的值。)

更新相同文档导航的导航API条目,需要给定一个导航 navigation,一个会话历史条目 destinationSHE,以及一个NavigationType navigationType

  1. 如果navigation已禁用条目和事件,则返回。

  2. oldCurrentNHEnavigation当前条目

  3. disposedNHEs为一个新的空列表

  4. 如果navigationType为"traverse",则

    1. navigation当前条目索引设置为destinationSHEnavigation获取导航API条目索引的结果。

    2. 断言navigation当前条目索引 不为 −1。

    此算法仅在同文档遍历时调用。跨文档遍历将改为调用 为新文档初始化导航 API 条目更新导航 API 条目以进行重新激活

  5. 否则,如果 navigationType 为 "push",则

    1. navigation当前条目索引 设置为 navigation当前条目索引 + 1。

    2. inavigation当前条目索引

    3. i < navigation条目列表大小

      1. 追加 navigation条目列表[i] 到 disposedNHEs

      2. i 设置为 i + 1。

    4. 移除 disposedNHEs 中的所有项,从 navigation条目列表 中。

  6. 否则,如果 navigationType 为 "replace",则

    1. 追加 oldCurrentNHEdisposedNHEs

  7. 如果 navigationType 为 "push" 或 "replace",则

    1. newNHE 为在 navigation相关领域 中创建的 新的 NavigationHistoryEntry

    2. newNHE会话历史条目 设置为 destinationSHE

    3. navigation条目列表[navigation当前条目索引] 设置为 newNHE

  8. 如果 navigation正在进行的 API 方法跟踪器 不为空,则 通知已提交的条目,给定 navigation正在进行的 API 方法跟踪器navigation当前条目

    在触发 disposecurrententrychange 事件之前执行此操作非常重要,因为事件处理程序可能会启动另一个导航,或以其他方式更改 navigation正在进行的 API 方法跟踪器 的值。

  9. 准备运行脚本,给定 navigation相关设置对象

    请参阅 其他导航 API 事件的讨论,以了解我们为什么要这样做。

  10. 触发名为 currententrychange 的事件,在 navigation 上使用 NavigationCurrentEntryChangeEvent,其 navigationType 属性初始化为 navigationType,其 from 初始化为 oldCurrentNHE

  11. 对于每个 disposedNHEsdisposedNHE

    1. 触发名为 dispose 的事件,在 disposedNHE 上。

  12. 运行脚本后清理,给定 navigation相关设置对象

在实现中,同文档导航可能会导致 会话历史条目 从会话历史条目列表的末尾脱落而被处置。上述算法(或本标准的任何其他部分)尚未处理这种情况。请参阅 问题 #8620 以跟踪在这些情况下定义正确行为的进度。

7.2.6.5 NavigationHistoryEntry 接口
[Exposed=Window]
interface NavigationHistoryEntry : EventTarget {
  readonly attribute USVString? url;
  readonly attribute DOMString key;
  readonly attribute DOMString id;
  readonly attribute long long index;
  readonly attribute boolean sameDocument;

  any getState();

  attribute EventHandler ondispose;
};
entry.url

此导航历史条目的 URL。

如果条目对应于与当前不同的 Document(即,如果 sameDocument 为 false),并且该 Document 是使用 "no-referrer" 或 "origin" 的 引用来源策略 获取的,则它可以返回 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 都有一个关联的 会话历史条目,它是一个 会话历史条目

NavigationHistoryEntry nhe 由以下算法的返回值给出

  1. 如果 nhe相关全局对象关联的 Document 不是 完全活动 的,则返回空字符串。

  2. 返回 nhe会话历史条目导航 API 键

NavigationHistoryEntry nheID 由以下算法的返回值给出

  1. 如果 nhe相关全局对象关联的 Document 不是 完全活动 的,则返回空字符串。

  2. 返回 nhe会话历史条目导航 API ID

NavigationHistoryEntry nhe索引 由以下算法的返回值给出

  1. 如果 nhe相关全局对象关联的 Document 不是 完全活动 的,则返回 −1。

  2. 返回获取导航 API 条目索引的结果,该索引是this会话历史条目this相关全局对象导航 API中。

url 获取器的步骤如下

  1. documentthis相关全局对象关联的 Document

  2. 如果document 不是完全激活的,则返回空字符串。

  3. shethis会话历史条目

  4. 如果she文档不等于document,并且she文档状态请求引用者策略为“no-referrer”或“origin”,则返回 null。

  5. 返回sheURL序列化后的结果。

key 获取器的步骤是返回this

id 获取器的步骤是返回thisID

index 获取器的步骤是返回this索引

sameDocument 获取器的步骤如下

  1. documentthis相关全局对象关联的 Document

  2. 如果document 不是完全激活的,则返回 false。

  3. 如果this会话历史条目文档等于document,则返回 true,否则返回 false。

getState() 方法的步骤如下

  1. 如果this相关全局对象关联的 Document不是完全激活的,则返回 undefined。

  2. 返回StructuredDeserialize(this会话历史条目导航 API 状态)。重新抛出任何异常。

    理论上,如果尝试在可用内存不足的情况下反序列化大型ArrayBuffer,则可能会抛出异常。

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

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

返回一个 NavigationHistoryEntry 实例数组,表示当前导航历史条目列表,即此可导航对象的所有会话历史条目,这些条目与当前会话历史条目具有相同的源且连续。

navigation.currentEntry

返回与当前会话历史条目对应的NavigationHistoryEntry

navigation.updateCurrentEntry({ state })

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

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

navigation.canGoBack

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

navigation.canGoForward

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

entries() 方法的步骤如下

  1. 如果this已禁用条目和事件,则返回空列表。

  2. 返回this条目列表

    请注意,由于 Web IDL 的序列类型转换规则,这将在每次调用时创建一个新的 JavaScript 数组对象。也就是说,navigation.entries() !== navigation.entries()

currentEntry 获取器的步骤是返回this当前条目

updateCurrentEntry(options) 方法的步骤如下

  1. currentthis当前条目

  2. 如果current 为 null,则抛出一个"InvalidStateError"DOMException

  3. serializedStateStructuredSerializeForStorage(options["state"]),重新抛出任何异常。

  4. current会话历史条目导航 API 状态设置为serializedState

  5. 触发一个名为currententrychange的事件,在this上使用NavigationCurrentEntryChangeEvent,其navigationType属性初始化为 null,其from初始化为current

canGoBack 获取器的步骤如下

  1. 如果this已禁用条目和事件,则返回 false。

  2. 断言this当前条目索引 不是 −1。

  3. 如果 this当前条目索引 为 0,则返回 false。

  4. 返回true。

canGoForward 获取器的步骤如下

  1. 如果 this 已禁用条目和事件,则返回 false。

  2. 断言this当前条目索引 不是 −1。

  3. 如果 this当前条目索引 等于 this条目列表大小 − 1,则返回 false。

  4. 返回true。

{ committedfinished } = navigation.navigate(url)
{ committedfinished } = navigation.navigate(urloptions)

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

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

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

在所有情况下,当返回的 Promise 完成时,它将使用已导航到的 NavigationHistoryEntry

{ committedfinished } = navigation.reload(options)

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

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

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

{ committedfinished } = navigation.traverseTo(key)
{ committedfinished } = navigation.traverseTo(key,{ info })

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

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

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

{ committedfinished } = navigation.back(key)
{ committedfinished } = navigation.back(key,{ info })

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

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

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

{ committed, finished } = navigation.forward(key)
{ committed, finished } = navigation.forward(key, { info })

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

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

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

navigate(url, options) 方法的步骤如下:

  1. urlRecord为给定url(相对于this相关设置对象解析 URL的结果。

  2. 如果urlRecord为失败,则返回"SyntaxError"DOMException早期错误结果

  3. documentthis相关全局对象关联的 Document

  4. 如果options["history"] 为 "push",并且给定urlRecorddocument导航必须为替换导航,则返回"NotSupportedError"DOMException早期错误结果

  5. stateoptions["state"],如果它存在;否则为 undefined。

  6. serializedStateStructuredSerializeForStorage(state)。如果这抛出异常,则返回该异常的早期错误结果

    重要的是尽早执行此步骤,因为序列化可能会调用 Web 开发人员代码,而这反过来可能会更改我们在后续步骤中检查的各种内容。

  7. 如果document不是完全活动状态,则返回"InvalidStateError"DOMException早期错误结果

  8. 如果document卸载计数器大于 0,则返回"InvalidStateError"DOMException早期错误结果

  9. infooptions["info"],如果它存在;否则为 undefined。

  10. apiMethodTracker可能为this设置即将到来的非遍历 API 方法跟踪器给定infoserializedState的结果。

  11. 导航document节点可导航对象urlRecord,使用document,其中historyHandling设置为options["history"],navigationAPIState设置为serializedState

    location.assign()及其同类方法(这些方法在同源域边界之间公开)不同,navigation.navigate()只能被具有对window.navigation属性的直接同步访问权限的代码访问。因此,我们避免了关于为导航指定源文档的复杂性,并且我们不需要处理沙箱允许导航检查及其附带的exceptionsEnabled标志。我们只是将所有导航视为来自与此Navigation对象本身(即document)对应的Document

  12. 如果this即将到来的非遍历 API 方法跟踪器apiMethodTracker,则

    如果即将到来的非遍历 API 方法跟踪器仍然为apiMethodTracker,这意味着navigate算法在到达内部 navigate 事件触发算法(该算法将将该即将到来的 API 方法跟踪器提升为正在进行的)之前就退出了。

    1. this即将到来的非遍历 API 方法跟踪器设置为 null。

    2. 返回"AbortError"DOMException早期错误结果

  13. 返回apiMethodTracker导航 API 方法跟踪器派生结果

reload(options) 方法的步骤如下:

  1. documentthis相关全局对象关联的 Document

  2. serializedStateStructuredSerializeForStorage(undefined)。

  3. 如果options["state"]存在,则将serializedState设置为StructuredSerializeForStorage(options["state"])。如果这抛出异常,则返回该异常的早期错误结果

    重要的是尽早执行此步骤,因为序列化可能会调用 Web 开发人员代码,而这反过来可能会更改我们在后续步骤中检查的各种内容。

  4. 否则

    1. currentthis当前条目

    2. 如果current不为 null,则将serializedState设置为current会话历史条目导航 API 状态

  5. 如果document不是完全活动状态,则返回"InvalidStateError"DOMException早期错误结果

  6. 如果document卸载计数器大于 0,则返回"InvalidStateError"DOMException早期错误结果

  7. 如果存在,则令 infooptions["info"];否则为未定义。

  8. apiMethodTracker 为针对 this,根据 infoserializedState 可能设置即将到来的非遍历 API 方法跟踪器 的结果。

  9. 使用 navigationAPIState 设置为 serializedState重新加载 document节点可导航对象

  10. 返回 apiMethodTracker导航 API 方法跟踪器派生结果

traverseTo(key, options) 方法的步骤如下

  1. 如果 this当前条目索引 为 −1,则返回 "InvalidStateError" DOMException早期错误结果

  2. 如果 this条目列表包含会话历史条目导航 API 密钥 等于 keyNavigationHistoryEntry,则返回 "InvalidStateError" DOMException早期错误结果

  3. 返回根据 thiskeyoptions 执行导航 API 遍历 的结果。

back(options) 方法的步骤如下

  1. 如果 this当前条目索引 为 −1 或 0,则返回 "InvalidStateError" DOMException早期错误结果

  2. keythis条目列表[this当前条目索引 − 1] 的 会话历史条目导航 API 密钥

  3. 返回根据 thiskeyoptions 执行导航 API 遍历 的结果。

forward(options) 方法的步骤如下

  1. 如果 this当前条目索引 为 −1 或等于 this条目列表大小 − 1,则返回 "InvalidStateError" DOMException早期错误结果

  2. keythis条目列表[this当前条目索引 + 1] 的 会话历史条目导航 API 密钥

  3. 返回根据 thiskeyoptions 执行导航 API 遍历 的结果。

要根据 Navigation navigation、字符串 keyNavigationOptions options 执行导航 API 遍历

  1. documentnavigation相关全局对象关联的 Document

  2. 如果 document 不是 完全激活的,则返回 "InvalidStateError" DOMException早期错误结果

  3. 如果 document卸载计数器 大于 0,则返回 "InvalidStateError" DOMException早期错误结果

  4. currentnavigation当前条目

  5. 如果 key 等于 current会话历史条目导航 API 密钥,则返回 «[ "committed" → 使用 current 解析的 Promise,"finished" → 使用 current 解析的 Promise ]»。

  6. 如果 navigation即将到来的遍历 API 方法跟踪器[key] 存在,则返回 navigation即将到来的遍历 API 方法跟踪器[key] 的 导航 API 方法跟踪器派生结果

  7. 如果存在,则令 infooptions["info"];否则为未定义。

  8. apiMethodTracker 为根据 keyinfo navigation 添加即将到来的遍历 API 方法跟踪器 的结果。

  9. navigabledocument节点可导航对象

  10. traversablenavigable可遍历可导航对象

  11. sourceSnapshotParams 为根据 document 获取源快照参数快照 的结果。

  12. 将以下会话历史遍历步骤 附加到 traversable

    1. navigableSHEs 为根据 navigable 获取会话历史条目 的结果。

    2. targetSHEnavigableSHEs 中其 导航 API 密钥key会话历史条目。如果不存在这样的条目,则

      1. 导航和遍历任务源 上,针对 navigation相关全局对象 排队一个全局任务,以 "InvalidStateError" DOMException 拒绝 apiMethodTracker 的完成 Promise

      2. 中止这些步骤。

      如果 navigation条目列表navigableSHEs 相比已过时,则会走这条路径,这可能会在所有相关线程和进程正在同步以响应历史更改的短暂时间内发生。

    3. 如果 targetSHEnavigable活动会话历史条目,则中止这些步骤。

      如果先前 排队 的遍历已将我们带到此 会话历史条目,则可能会发生这种情况。在这种情况下,先前的遍历将已经处理了 apiMethodTracker

    4. result 为对traversable 应用由targetSHE步骤 给出的遍历历史步骤 的结果,前提是给定 sourceSnapshotParamsnavigable 和 "none"。

    5. 如果result 为 "canceled-by-beforeunload",则在由navigation相关全局对象 给出的导航和遍历任务源排队一个全局任务,以拒绝apiMethodTracker 的已完成 Promise,并使用在navigation相关领域 中创建的新"AbortError" DOMException

    6. 如果result 为 "initiator-disallowed",则在由navigation相关全局对象 给出的导航和遍历任务源排队一个全局任务,以拒绝apiMethodTracker 的已完成 Promise,并使用在navigation相关领域 中创建的新"SecurityError" DOMException

      result 为 "canceled-by-beforeunload" 或 "initiator-disallowed" 时,navigate 事件从未触发,中止正在进行的导航 将不正确;它将导致一个navigateerror 事件,而没有前面的navigate 事件。

      在 "canceled-by-navigate" 的情况下,navigate 确实触发了,但是内部 navigate 事件触发算法 将负责中止正在进行的导航

  13. 返回apiMethodTracker导航 API 方法跟踪器派生的结果

对于异常e,其早期错误结果 是一个由 «[ "committed" → e 拒绝的 Promise,"finished" → e 拒绝的 Promise ]» 给出的NavigationResult 字典实例。

对于导航 API 方法跟踪器,其导航 API 方法跟踪器派生的结果 是一个由 «[ "committed" → apiMethodTracker已确认 Promise,"finished" → apiMethodTracker已完成 Promise ]» 给出的NavigationResult 字典实例。

7.2.6.8 正在进行的导航跟踪

在任何给定的导航期间(广义上的),Navigation 对象需要跟踪以下内容

对于所有导航
状态持续时间解释
NavigateEvent在事件触发期间以便如果在事件触发时取消导航,我们可以取消 事件
事件的中止控制器直到传递给intercept() 的处理程序返回的所有 Promise 都已解决以便如果导航被取消,我们可以发出中止信号
是否聚焦 了一个新元素直到传递给intercept() 的处理程序返回的所有 Promise 都已解决以便如果有一个,焦点就不会重置
正在导航到的NavigationHistoryEntry从确定它开始,直到传递给intercept() 的处理程序返回的所有 Promise 都已解决以便我们知道用什么来解析任何committedfinished Promise
任何返回的finished Promise直到传递给intercept() 的处理程序返回的所有 Promise 都已解决以便我们可以适当地解析或拒绝它
对于非 "traverse" 导航
状态持续时间解释
任何state在事件触发期间以便如果事件完成触发且未被取消,我们可以更新当前条目的导航 API 状态
对于 "traverse" 导航
状态持续时间解释
任何info直到排队触发navigate 事件的任务以便我们可以使用它在通过会话历史遍历队列 后触发navigate
任何返回的committed Promise直到会话历史更新(在同一任务中)以便我们可以适当地解析或拒绝它
是否调用了intercept()直到会话历史更新(在同一任务中)以便我们可以抑制正常的滚动恢复逻辑,以支持由scroll 选项给出的行为

此外,我们不能假设在任何给定时间只有一个导航请求,因为 Web 开发人员代码例如

const p1 = navigation.navigate(url1).finished;
const p2 = navigation.navigate(url2).finished;

也就是说,在这种情况下,我们需要确保在导航到 url2 时,我们仍然保留 Promise p1 以便我们可以拒绝它。我们不能仅仅在第二次调用navigate() 时就丢弃任何正在进行的导航 Promise。

我们最终通过将以下内容与每个Navigation 关联来实现这一切

此处未存储在导航 API 方法跟踪器 中的状态是即使对于非通过导航 API 方法发起的导航也需要跟踪的状态。

导航 API 方法跟踪器 是一个具有以下结构体

所有这些状态随后通过以下算法进行管理。

可能设置即将到来的非遍历 API 方法跟踪器,给定一个Navigation navigation、一个 JavaScript 值info 和一个序列化状态-或-null serializedState

  1. committedPromisefinishedPromise 为在navigation相关领域 中创建的新 Promise。

  2. 标记为已处理 finishedPromise

    网页开发者并不一定关心 finishedPromise 是否被拒绝。

    • 他们可能只关心 committedPromise

    • 他们可能在同一个任务中进行多次同步导航,在这种情况下,除了最后一次之外的所有导航都将被中止(导致它们的 finishedPromise 被拒绝)。这可能是应用程序错误,但也可能是应用程序不同部分覆盖彼此操作的紧急功能。

    • 他们可能更愿意监听其他过渡失败信号,而不是 finishedPromise,例如,navigateerror 事件,或 navigation.transition.finished Promise。

    因此,我们将它标记为已处理,以确保它永远不会触发 unhandledrejection 事件。

  3. apiMethodTracker 为一个新的 导航 API 方法跟踪器,其中包含

    导航对象
    navigation
    null
    信息
    信息
    序列化状态
    serializedState
    已提交的条目
    null
    已提交的 Promise
    committedPromise
    已完成的 Promise
    finishedPromise
  4. 断言navigation即将到来的非遍历 API 方法跟踪器 为 null。

  5. 如果 navigation禁用条目和事件,则将 navigation即将到来的非遍历 API 方法跟踪器 设置为 apiMethodTracker

    如果 navigation 禁用条目和事件,则 committedPromisefinishedPromise 将永远不会 fulfilled(因为我们从未为这样的 Document 创建 NavigationHistoryEntry 对象,因此我们无法用任何东西来解析它们);没有 NavigationHistoryEntry 可以应用 serializedState;并且没有 navigate 事件可以包含 info。因此,我们根本不需要跟踪此 API 方法调用。

  6. 返回 apiMethodTracker

要给定一个 Navigation navigation、一个字符串 destinationKey 和一个 JavaScript 值 info 添加即将到来的遍历 API 方法跟踪器

  1. committedPromisefinishedPromise 为在 navigation相关 realm 中创建的新 Promise。

  2. 标记为已处理 finishedPromise

    请参阅关于为何执行此操作的 先前讨论

  3. apiMethodTracker 为一个新的 导航 API 方法跟踪器,其中包含

    导航对象
    navigation
    destinationKey
    信息
    信息
    序列化状态
    null
    已提交的条目
    null
    已提交的 Promise
    committedPromise
    已完成的 Promise
    finishedPromise
  4. navigation即将到来的遍历 API 方法跟踪器[key] 设置为 apiMethodTracker

  5. 返回 apiMethodTracker

要给定一个 Navigation navigation 和一个字符串或 null destinationKey 将即将到来的 API 方法跟踪器提升为正在进行

  1. 断言navigation正在进行的 API 方法跟踪器 为 null。

  2. 如果 destinationKey 不为 null,则

    1. 断言navigation即将到来的非遍历 API 方法跟踪器 为 null。

    2. 如果 navigation即将到来的遍历 API 方法跟踪器[destinationKey] 存在,则

      1. navigation正在进行的 API 方法跟踪器 设置为 navigation即将到来的遍历 API 方法跟踪器[destinationKey]。

      2. 移除 navigation即将到来的遍历 API 方法跟踪器[destinationKey]。

  3. 否则

    1. navigation正在进行的 API 方法跟踪器 设置为 navigation即将到来的非遍历 API 方法跟踪器

    2. navigation即将到来的非遍历 API 方法跟踪器 设置为 null。

清理 一个 导航 API 方法跟踪器 apiMethodTracker

  1. navigationapiMethodTracker导航对象

  2. 如果 navigation正在进行的 API 方法跟踪器apiMethodTracker,则将 navigation正在进行的 API 方法跟踪器 设置为 null。

  3. 否则

    1. keyapiMethodTracker

    2. 断言key 不为 null。

    3. 断言navigation即将到来的遍历 API 方法跟踪器[key] 存在

    4. 移除 navigation即将到来的遍历 API 方法跟踪器[key]。

要给定一个 导航 API 方法跟踪器 apiMethodTracker 和一个 NavigationHistoryEntry nhe 通知有关已提交的条目

  1. apiMethodTracker已提交的条目 设置为 nhe

  2. 如果 apiMethodTracker序列化状态 不为 null,则将 nhe会话历史条目导航 API 状态 设置为 apiMethodTracker序列化状态

    如果它为 null,则我们通过 navigation.traverseTo() 遍历到 nhe,这不允许更改状态。

    此时,apiMethodTracker序列化状态 不再需要。实现可能希望将其清除,以避免将其保持在 导航 API 方法跟踪器 的生命周期内。

  3. 使用 nhe 解析 apiMethodTracker已提交的 Promise

    此时,apiMethodTracker已提交的 Promise 仅在尚未将其返回给作者代码的情况下才需要。实现可能希望将其清除,以避免将其保持在 导航 API 方法跟踪器 的生命周期内。

要为 导航 API 方法跟踪器 apiMethodTracker 解析已完成的 Promise

  1. 使用其 已提交的条目 解析 apiMethodTracker已提交的 Promise

    通常,通知有关已提交的条目 之前已在 apiMethodTracker 上调用,因此这将不会执行任何操作。但是,在某些情况下,解析已完成的 Promise 是直接调用的,在这种情况下,此步骤是必要的。

  2. 使用其 已提交的条目 解析 apiMethodTracker已完成的 Promise

  3. 清理 apiMethodTracker

要使用 JavaScript 值 exception导航 API 方法跟踪器 apiMethodTracker 拒绝已完成的 Promise

  1. 使用 exception 拒绝 apiMethodTracker已提交的 Promise

    如果 apiMethodTracker已提交的 Promise 之前已通过 通知有关已提交的条目 解析,则这将不会执行任何操作。

  2. 使用 exception 拒绝 apiMethodTracker已完成的 Promise

  3. 清理 apiMethodTracker

要给定一个 Navigation navigation 和一个可选的 DOMException error 中止正在进行的导航

  1. eventnavigation正在进行的 navigate 事件

  2. 断言event 不为 null。

  3. navigation在正在进行的导航期间焦点已更改 设置为 false。

  4. navigation在正在进行的导航期间抑制正常的滚动恢复 设置为 false。

  5. 如果未给出 error,则令 error 为在 navigation相关 realm 中创建的新 "AbortError" DOMException

  6. 如果 event分派标志 已设置,则将 event已取消标志 设置为 true。

  7. 在给定 error 的情况下,在 event中止控制器 上触发 信号中止

  8. navigation正在进行的 navigate 事件 设置为 null。

  9. errorInfo 为从 error提取错误信息 的结果。

    例如,如果由于调用了 window.stop() 而到达此算法,则这些属性可能会根据调用 window.stop() 的脚本行进行初始化。但如果这是因为用户点击了停止按钮,则这些属性可能会使用默认值(如空字符串或 0)。

  10. navigation 上使用 ErrorEvent 触发一个名为 navigateerror 的事件,并根据 errorInfo 初始化其他属性。

  11. 如果 navigation正在进行的 API 方法跟踪器 不为 null,则使用 error 拒绝 apiMethodTracker 的已完成的 Promise

  12. 如果 navigation过渡 不为 null,则

    1. 使用 error 拒绝 navigation过渡已完成的 Promise

    2. navigation过渡 设置为 null。

在可导航的 navigable通知导航 API 关于中止导航

  1. 如果此算法正在 navigable活动窗口相关代理事件循环 上运行,则继续执行以下步骤。否则,在给定 navigable活动窗口导航和遍历任务源排队一个全局任务,以运行以下步骤。

  2. navigationnavigable活动窗口导航 API

  3. 如果 navigation正在进行的 navigate 事件 为 null,则返回。

  4. 给定 navigation 中止正在进行的导航

给定可导航的 navigable 通知导航 API 关于子可导航的销毁

  1. navigable通知导航 API 关于中止导航

  2. navigationnavigable活动窗口导航 API

  3. traversalAPIMethodTrackersnavigation即将到来的遍历 API 方法跟踪器克隆

  4. 对于 traversalAPIMethodTrackers 的每个 apiMethodTracker:使用在 navigation相关领域 中创建的新 "AbortError" DOMException 拒绝 apiMethodTracker 的已完成的 Promise


正在进行的导航概念最直接地通过 navigation.transition 属性公开给 Web 开发人员,该属性是 NavigationTransition 接口的实例。

[Exposed=Window]
interface NavigationTransition {
  readonly attribute NavigationType navigationType;
  readonly attribute NavigationHistoryEntry from;
  readonly attribute Promise<undefined> finished;
};
navigation.transition

一个表示任何尚未到达 navigatesuccessnavigateerror 阶段的正在进行的导航的 NavigationTransition,如果存在;或者如果不存在此类过渡,则为 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 都有一个过渡,它是一个 NavigationTransition 或 null,最初为 null。

transition 获取器步骤是返回 this过渡

每个 NavigationTransition 都有一个关联的导航类型,它是一个 NavigationType

每个 NavigationTransition 都有一个关联的来自条目,它是一个 NavigationHistoryEntry

每个 NavigationTransition 都有一个关联的已完成的 Promise,它是一个 Promise。

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

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

finished 获取器步骤是返回 this已完成的 Promise

[Exposed=Window]
interface NavigationActivation {
  readonly attribute NavigationHistoryEntry? from;
  readonly attribute NavigationHistoryEntry entry;
  readonly attribute NavigationType navigationType;
};
navigation.activation

一个 NavigationActivation,包含有关最近一次跨文档导航的信息,即“激活”此 Document 的导航。

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

navigation.activation.entry

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

navigation.activation.from

一个 NavigationHistoryEntry,表示当前 Document 之前处于活动状态的 Document。如果前一个 Document 与当前文档的 源相同 或它是 初始的 about:blank Document,则此值将为 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.6.10 navigate 事件

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

7.2.6.10.1 NavigateEvent 接口
[Exposed=Window]
interface NavigateEvent : Event {
  constructor(DOMString type, NavigateEventInit eventInitDict);

  readonly attribute NavigationType navigationType;
  readonly attribute NavigationDestination destination;
  readonly attribute boolean canIntercept;
  readonly attribute boolean userInitiated;
  readonly attribute boolean hashChange;
  readonly attribute AbortSignal signal;
  readonly attribute FormData? formData;
  readonly attribute DOMString? downloadRequest;
  readonly attribute any info;
  readonly attribute boolean hasUAVisualTransition;

  undefined intercept(optional NavigationInterceptOptions options = {});
  undefined scroll();
};

dictionary NavigateEventInit : EventInit {
  NavigationType navigationType = "push";
  required NavigationDestination destination;
  boolean canIntercept = false;
  boolean userInitiated = false;
  boolean hashChange = false;
  required AbortSignal signal;
  FormData? formData = null;
  DOMString? downloadRequest = null;
  any info;
  boolean hasUAVisualTransition = false;
};

dictionary NavigationInterceptOptions {
  NavigationInterceptHandler handler;
  NavigationFocusReset focusReset;
  NavigationScrollBehavior scroll;
};

enum NavigationFocusReset {
  "after-transition",
  "manual"
};

enum NavigationScrollBehavior {
  "after-transition",
  "manual"
};

callback NavigationInterceptHandler = Promise<undefined> ();
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

表示此导航提交的表单条目的 FormData,如果此导航是表示 POST 表单提交 的 " push" 或 " replace" 导航;否则为 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 指定的 fragment(如果存在)。

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

每个 NavigateEvent 都有一个 拦截状态,该状态可以是“none”、“intercepted”、“committed”、“scrolled”或“finished”,最初为“none”。

每个 NavigateEvent 都有一个 导航处理程序列表,这是一个 NavigationInterceptHandler 回调的 列表,最初为空。

每个 NavigateEvent 都有一个 焦点重置行为,一个 NavigationFocusReset 或 null,最初为 null。

每个 NavigateEvent 都有一个 滚动行为,一个 NavigationScrollBehavior 或 null,最初为 null。

每个 NavigateEvent 都有一个 中止控制器,一个 AbortController 或 null,最初为 null。

每个 NavigateEvent 都有一个 经典历史 API 状态,一个 序列化状态 或 null。它仅在事件的 navigationType 为“push”或“replace”的某些情况下使用,并在事件 触发时适当地设置。

navigationTypedestinationcanInterceptuserInitiatedhashChangesignalformDatadownloadRequestinfohasUAVisualTransition 属性必须返回其初始化的值。

intercept(options) 方法的步骤是

  1. 给定 this执行共享检查

  2. 如果 thiscanIntercept 属性初始化为 false,则抛出一个 "SecurityError" DOMException

  3. 如果 this分派标志 未设置,则抛出一个 "InvalidStateError" DOMException

  4. 断言this拦截状态 为“none”或“intercepted”。

  5. this拦截状态 设置为“intercepted”。

  6. 如果 options["handler"] 存在,则将其 附加this导航处理程序列表

  7. 如果 options["focusReset"] 存在,则

    1. 如果 this焦点重置行为 不为 null,并且它不等于 options["focusReset"],则用户代理可能会 向控制台报告警告,指示先前对 intercept() 的调用的 focusReset 选项被此新值覆盖,并且先前值将被忽略。

    2. this焦点重置行为 设置为 options["focusReset"]。

  8. 如果 options["scroll"] 存在,则

    1. 如果 this滚动行为 不为 null,并且它不等于 options["scroll"],则用户代理可能会 向控制台报告警告,指示先前对 intercept() 的调用的 scroll 选项被此新值覆盖,并且先前值将被忽略。

    2. this滚动行为 设置为 options["scroll"]。

scroll() 方法的步骤是

  1. 给定 this执行共享检查

  2. 如果 this拦截状态 不是“committed”,则抛出一个 "InvalidStateError" DOMException

  3. 给定 this处理滚动行为

对于 NavigateEvent event执行共享检查

  1. 如果 event相关全局对象关联的 Document 不是 完全活动的,则抛出一个 "InvalidStateError" DOMException

  2. 如果 eventisTrusted 属性被初始化为 false,则抛出一个 "SecurityError" DOMException

  3. 如果 eventcanceled 标志 被设置,则抛出一个 "InvalidStateError" DOMException

7.2.6.10.2 NavigationDestination 接口
[Exposed=Window]
interface NavigationDestination {
  readonly attribute USVString url;
  readonly attribute DOMString key;
  readonly attribute DOMString id;
  readonly attribute long long index;
  readonly attribute boolean sameDocument;

  any getState();
};
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。

每个 NavigationDestination 都有一个 URL,它是一个 URL

每个 NavigationDestination 都有一个 条目,它是一个 NavigationHistoryEntry 或 null。

当且仅当 NavigationDestination 对应于“traverse”导航时,它将不为 null。

每个 NavigationDestination 都有一个 状态,它是一个 序列化状态

每个 NavigationDestination 都有一个 是否为同一文档,它是一个布尔值。


url 获取器步骤是返回 thisURL序列化

key 获取器步骤是

  1. 如果 this条目 为 null,则返回空字符串。

  2. 返回 this条目key

id 获取器步骤是

  1. 如果 this条目 为 null,则返回空字符串。

  2. 返回 this条目ID

index 获取器步骤是

  1. 如果 this条目 为 null,则返回 -1。

  2. 返回 this条目index

sameDocument 获取器步骤是返回 this是否为同一文档

getState() 方法步骤是返回 StructuredDeserialize(this状态)。

标准的其他部分通过本节中给出的系列包装算法触发 navigate 事件。

在给定的 Navigation navigation触发 traverse navigate 事件,给定一个 会话历史条目 destinationSHE 和一个可选的 用户导航参与 userInvolvement(默认为“none”)

  1. event 为给定 NavigateEventnavigation相关领域创建事件 的结果。

  2. event经典历史 API 状态 设置为 null。

  3. destination 为在 navigation相关领域 中创建的 新的 NavigationDestination

  4. destinationURL 设置为 destinationSHEURL

  5. destinationNHEnavigation条目列表NavigationHistoryEntry,其 会话历史条目destinationSHE,如果没有这样的 NavigationHistoryEntry 则为 null。

  6. 如果 destinationNHE 不为 null,则

    1. destination条目 设置为 destinationNHE

    2. destination状态 设置为 destinationSHE导航 API 状态

  7. 否则,

    1. destination条目 设置为 null。

    2. destination状态 设置为 StructuredSerializeForStorage(null)。

  8. 如果 destinationSHE文档 等于 navigation相关全局对象关联的 Document,则将 destination是否为同一文档 设置为 true;否则为 false。

  9. 返回执行给定 navigation、"traverse"、eventdestinationuserInvolvement、null 和 null 的 内部 navigate 事件触发算法 的结果。

在给定的 导航 navigation 上,触发一个 导航类型 navigationType推送/替换/重新加载 navigate 事件,一个 URL destinationURL,一个布尔值 isSameDocument,一个可选的 用户导航参与 userInvolvement(默认为 "none"),一个可选的 条目列表 或 null formDataEntryList(默认为 null),一个可选的 序列化状态 navigationAPIState(默认为 StructuredSerializeForStorage(null)),以及一个可选的 序列化状态 或 null classicHistoryAPIState(默认为 null)。

  1. event 为在 navigation相关领域 中,根据 NavigateEvent 创建事件 的结果。

  2. event经典历史 API 状态 设置为 classicHistoryAPIState

  3. destination 为在 navigation相关领域 中创建的 NavigationDestination 新实例

  4. destinationURL 设置为 destinationURL

  5. destination条目 设置为 null。

  6. destination状态 设置为 navigationAPIState

  7. destination是否为同一文档 设置为 isSameDocument

  8. 返回在给定 navigationnavigationTypeeventdestinationuserInvolvementformDataEntryList 和 null 的情况下,执行 内部 navigate 事件触发算法 的结果。

在给定的 导航 navigation 上,触发一个 下载请求 navigate 事件,一个 URL destinationURL,一个 用户导航参与 userInvolvement,以及一个字符串 filename

  1. event 为在 navigation相关领域 中,根据 NavigateEvent 创建事件 的结果。

  2. event经典历史 API 状态 设置为 null。

  3. destination 为在 navigation相关领域 中创建的 NavigationDestination 新实例

  4. destinationURL 设置为 destinationURL

  5. destination条目 设置为 null。

  6. destination状态 设置为 StructuredSerializeForStorage(null)。

  7. destination是否为同一文档 设置为 false。

  8. 返回在给定 navigation,"push",eventdestinationuserInvolvement,null 和 filename 的情况下,执行 内部 navigate 事件触发算法 的结果。

内部 navigate 事件触发算法由以下步骤组成,给定一个 导航 navigation,一个 导航类型 navigationType,一个 NavigateEvent event,一个 NavigationDestination destination,一个 用户导航参与 userInvolvement,一个 条目列表 或 null formDataEntryList,以及一个字符串或 null downloadRequestFilename

  1. 如果 navigation 禁用了条目和事件,则

    1. 断言navigation正在进行的 API 方法跟踪器 为 null。

    2. 断言navigation即将到来的非遍历 API 方法跟踪器 为 null。

    3. 断言navigation即将到来的遍历 API 方法跟踪器 为空

    4. 返回true。

    这些断言成立,因为当条目和事件被禁用时,traverseTo()back()forward() 将立即失败(因为没有条目可供遍历),如果我们的起点是 navigate()reload(),那么我们 避免 在第一时间设置 即将到来的非遍历 API 方法跟踪器

  2. destinationKey 为 null。

  3. 如果 destination条目 不为 null,则将 destinationKey 设置为 destination条目

  4. 断言destinationKey 不是空字符串。

  5. 在给定 navigationdestinationKey 的情况下,将即将到来的 API 方法跟踪器提升为正在进行的

  6. apiMethodTrackernavigation正在进行的 API 方法跟踪器

  7. navigablenavigation相关全局对象navigable

  8. documentnavigation相关全局对象关联的 Document

  9. 如果 document 可以将其 URL 重写destinationURL,并且 destination是否为同一文档 为 true 或 navigationType 不为 "traverse",则将 eventcanIntercept 初始化为 true。否则,将其初始化为 false。

  10. 如果以下任一条件为真:

    则将 eventcancelable 初始化为 true。否则,将其初始化为 false。

  11. eventtype 初始化为 "navigate"。

  12. eventnavigationType 初始化为 navigationType

  13. eventdestination 初始化为 destination

  14. eventdownloadRequest 初始化为 downloadRequestFilename

  15. 如果 apiMethodTracker 不为 null,则将 eventinfo 初始化为 apiMethodTrackerinfo。否则,将其初始化为 undefined。

    此时,apiMethodTrackerinfo 不再需要,可以将其设为 null,而不是将其保持在 导航 API 方法跟踪器 的生命周期内。

  16. 如果用户代理执行了视觉转换以显示 document最新条目 的缓存渲染状态,则将 eventhasUAVisualTransition 初始化为 true。否则,将其初始化为 false。

  17. event中止控制器 设置为在 navigation相关领域 中创建的 AbortController 新实例

  18. eventsignal 初始化为 event中止控制器signal

  19. currentURLdocumentURL

  20. 如果以下所有条件都为真:

    则将 eventhashChange 初始化为 true。否则,将其初始化为 false。

    这里的第一个条件意味着,对于 片段导航hashChange 将为 true,但对于像 history.pushState(undefined, "", "#fragment") 这样的情况则为 false。

  21. 如果 userInvolvement 不是 "none",则将 eventuserInitiated 初始化为 true。否则,将其初始化为 false。

  22. 如果 formDataEntryList 不为 null,则将 eventformData 初始化为在 navigation相关领域中创建的 新的 FormData,并将其与 formDataEntryList 关联。否则,将其初始化为 null。

  23. 断言navigation正在进行的 navigate 事件 为 null。

  24. navigation正在进行的 navigate 事件 设置为 event

  25. navigation导航期间焦点是否发生变化 设置为 false。

  26. navigation导航期间是否抑制正常的滚动恢复 设置为 false。

  27. dispatchResult 为在 navigation分派 event 的结果。

  28. 如果 dispatchResult 为 false

    1. 如果 navigationType 为 "traverse",则根据 navigation相关全局对象 消耗历史操作的用户激活

    2. 如果 event中止控制器信号中止,则根据 navigation 中止正在进行的导航

    3. 返回 false。

  29. 如果 event拦截状态 不是 "none" 或 event目标是否为同一文档 为 true,则令 endResultIsSameDocument 为 true。

  30. 根据 navigation相关设置对象 准备运行脚本

    这样做是为了避免在任何 currententrychange 事件处理程序运行后,由于即将发生的 URL 和历史更新步骤导致 JavaScript 执行上下文栈 变为空。如果栈在那个时候变为空,那么它将立即 执行微任务检查点,导致各种 promise 履行处理程序与事件处理程序交错运行,并在传递给 navigateEvent.intercept() 的任何处理程序之前运行。这是不可取的,因为这意味着 promise 处理程序顺序与 currententrychange 事件处理程序顺序与 intercept() 处理程序顺序将取决于导航是在 JavaScript 执行上下文栈为空(例如,因为导航是由用户发起的)还是非空(例如,因为导航是由 JavaScript API 调用引起的)的情况下发生的。

    通过在此步骤中将一个原本不必要的 JavaScript 执行上下文 放到栈上,我们实际上抑制了 执行微任务检查点 算法,直到稍后,从而确保顺序始终是:currententrychange 事件处理程序,然后是 intercept() 处理程序,然后是 promise 处理程序。

  31. 如果 event拦截状态 不是 "none"

    1. event拦截状态 设置为 "committed"。

    2. fromNHEnavigation当前条目

    3. 断言fromNHE 不为 null。

    4. navigation转换 设置为在 navigation相关领域中创建的 新的 NavigationTransition,其 导航类型navigationType,其 起始条目fromNHE,并且其 完成 promise 为在 navigation相关领域中创建的新 promise。

    5. navigation转换完成 promise 标记为已处理

      请参阅 关于其他完成 promise 的讨论,以了解这样做的原因。

    6. 如果 navigationType 为 "traverse",则将 navigation导航期间是否抑制正常的滚动恢复 设置为 true。

      如果 event滚动行为 设置为 "after-transition",则滚动恢复将在 完成 相关的 NavigateEvent 的过程中发生。否则,将不会进行滚动恢复。也就是说,任何被 intercept() 拦截的导航都不会经过正常的滚动恢复过程;此类导航的滚动恢复要么由 Web 开发人员手动完成,要么在转换后完成。

    7. 如果 navigationType 为 "push" 或 "replace",则根据 documentevent目标URL 运行 URL 和历史更新步骤,其中 序列化数据 设置为 event经典历史 API 状态历史处理 设置为 navigationType

      如果 navigationType 为 "reload",则我们将 重新加载 转换为 "同一文档重新加载",对于这种情况,URL 和历史更新步骤 不适用。与导航 API 相关的操作仍然会发生,例如,如果这是由对 navigation.reload() 的调用引起的,则更新 活动会话历史条目导航 API 状态,以及所有 正在进行的导航跟踪

      如果 navigationType 为 "traverse",则此事件触发是作为 遍历过程的一部分发生的,并且该过程将负责执行适当的会话历史条目更新。

  32. 如果 endResultIsSameDocument 为 true

    1. promisesList 为一个空的 列表

    2. 对于 event导航处理程序列表中的每个 handler

      1. 将使用空参数列表 调用 handler 的结果 追加promisesList

    3. 如果 promisesList大小 为 0,则将 promisesList 设置为 « 一个以 undefined 解析的 promise »。

      当给定零个 Promise 与 ≥1 个 Promise 时,等待所有 计划其成功和失败步骤之间存在细微的时间差异。对于 等待所有 的大多数用法,这并不重要。但是,使用此 API,存在如此多的事件和 Promise 处理程序可能在同一时间触发,以至于差异非常容易观察到:它会导致事件/Promise 处理程序序列发生变化。(涉及的一些事件和 Promise 包括:navigatesuccess / navigateerrorcurrententrychangedisposeapiMethodTracker 的 Promise 以及 navigation.transition.finished Promise。)

    4. 等待所有 promisesList,并执行以下成功步骤

      1. 如果 event相关全局对象 不是 完全激活 的,则中止这些步骤。

      2. 如果 event中止控制器信号中止,则中止这些步骤。

      3. 断言event 等于 navigation正在进行的 navigate 事件

      4. navigation正在进行的 navigate 事件 设置为 null。

      5. 完成 event,并传递 true。

      6. 触发名为 navigatesuccess 的事件,目标为 navigation

      7. 如果 navigation过渡 不为 null,则使用 undefined 来 解析 navigation过渡已完成 Promise

      8. navigation过渡 设置为 null。

      9. 如果 apiMethodTracker 不为 null,则 解析 apiMethodTracker已完成 Promise

      以及给定原因 rejectionReason 的以下失败步骤

      1. 如果 event相关全局对象 不是 完全激活 的,则中止这些步骤。

      2. 如果 event中止控制器信号中止,则中止这些步骤。

      3. 断言event 等于 navigation正在进行的 navigate 事件

      4. navigation正在进行的 navigate 事件 设置为 null。

      5. 完成 event,并传递 false。

      6. errorInfo 为从 rejectionReason 提取错误信息 的结果。

      7. 触发名为 navigateerror 的事件,目标为 navigation,使用 ErrorEvent,并根据 errorInfo 初始化其他属性。

      8. 如果 navigation过渡 不为 null,则使用 rejectionReason拒绝 navigation过渡已完成 Promise

      9. navigation过渡 设置为 null。

      10. 如果 apiMethodTracker 不为 null,则使用 rejectionReason拒绝 apiMethodTracker已完成 Promise

  33. 否则,如果 apiMethodTracker 不为 null,则 清理 apiMethodTracker

  34. 运行脚本后清理,给定 navigation相关设置对象

    根据 前面的注释,这将停止抑制任何潜在的 Promise 处理程序微任务,导致它们在此处或之后运行。

  35. 如果 event拦截状态 为“none”,则返回 true。

  36. 返回 false。

通过调用 navigateEvent.intercept(),Web 开发人员可以抑制相同文档导航的正常滚动和焦点行为,而是在稍后时间调用类似跨文档导航的行为。本节中的算法在这些适当的后期时间点被调用。

完成 NavigateEvent event,给定一个布尔值 didFulfill

  1. 断言event拦截状态 不是“intercepted”或“finished”。

  2. 如果 event拦截状态 为“none”,则返回。

  3. 可能重置焦点,给定 event

  4. 如果 didFulfill 为 true,则 可能处理滚动行为,给定 event

  5. event拦截状态 设置为“finished”。

可能重置焦点,给定一个 NavigateEvent event

  1. 断言event拦截状态 为“committed”或“scrolled”。

  2. navigationevent相关全局对象导航 API

  3. focusChangednavigation在正在进行的导航期间焦点已更改

  4. navigation在正在进行的导航期间焦点已更改 设置为 false。

  5. 如果 focusChanged 为 true,则返回。

  6. 如果 event焦点重置行为 为“manual”,则返回。

    如果它被保留为 null,则我们将其视为“after-transition”,并继续执行。

  7. documentevent相关全局对象关联的 Document

  8. focusTargetdocument自动聚焦委托

  9. 如果 focusTarget 为 null,则将 focusTarget 设置为 document主体元素

  10. 如果 focusTarget 为 null,则将 focusTarget 设置为 document文档元素

  11. focusTarget 运行 聚焦步骤,并将 document视口 作为 备用目标

  12. 顺序焦点导航起点 移动到 focusTarget

可能处理滚动行为,给定一个 NavigateEvent event

  1. 断言event拦截状态 为“committed”或“scrolled”。

  2. 如果 event拦截状态 为“scrolled”,则返回。

  3. 如果 event滚动行为 为“manual”,则返回。

    如果它被保留为 null,则我们将其视为“after-transition”,并继续执行。

  4. 处理滚动行为,给定 event

处理滚动行为,给定一个 NavigateEvent event

  1. 断言event拦截状态 为“committed”。

  2. event拦截状态 设置为“scrolled”。

  3. 如果 eventnavigationType 被初始化为“traverse”或“reload”,则 恢复滚动位置数据,给定 event相关全局对象可导航对象活动会话历史条目

  4. 否则

    1. documentevent相关全局对象关联的 Document

    2. 如果 document指示部分 为 null,则 滚动到文档开头,给定 document[CSSOMVIEW]

    3. 否则,滚动到片段,给定 document

NavigateEvent 接口具有 其自己的专用部分,因为它很复杂。

7.2.7.1 NavigationCurrentEntryChangeEvent 接口
[Exposed=Window]
interface NavigationCurrentEntryChangeEvent : Event {
  constructor(DOMString type, NavigationCurrentEntryChangeEventInit eventInitDict);

  readonly attribute NavigationType? navigationType;
  readonly attribute NavigationHistoryEntry from;
};

dictionary NavigationCurrentEntryChangeEventInit : EventInit {
  NavigationType? navigationType = null;
  required NavigationHistoryEntry from;
};
event.navigationType

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

event.from

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

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

navigationTypefrom 属性必须返回其初始化的值。

7.2.7.2 PopStateEvent 接口

PopStateEvent/PopStateEvent

所有当前引擎都支持。

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

PopStateEvent

所有当前引擎都支持。

Firefox4+Safari6+Chrome4+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[Exposed=Window]
interface PopStateEvent : Event {
  constructor(DOMString type, optional PopStateEventInit eventInitDict = {});

  readonly attribute any state;
  readonly attribute boolean hasUAVisualTransition;
};

dictionary PopStateEventInit : EventInit {
  any state = null;
  boolean hasUAVisualTransition = false;
};
event.state

PopStateEvent/state

所有当前引擎都支持。

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

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

event.hasUAVisualTransition

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

state 属性必须返回其初始化的值。它表示事件的上下文信息,或者如果表示的状态是 Document 的初始状态,则返回 null。

hasUAVisualTransition 属性必须返回其初始化的值。

7.2.7.3 HashChangeEvent 接口

HashChangeEvent/HashChangeEvent

所有当前引擎都支持。

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
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 Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
[Exposed=Window]
interface HashChangeEvent : Event {
  constructor(DOMString type, optional HashChangeEventInit eventInitDict = {});

  readonly attribute USVString oldURL;
  readonly attribute USVString newURL;
};

dictionary HashChangeEventInit : EventInit {
  USVString oldURL = "";
  USVString newURL = "";
};
event.oldURL

HashChangeEvent/oldURL

所有当前引擎都支持。

Firefox6+Safari5.1+Chrome8+
Opera12.1+Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回先前当前的 会话历史条目URL

event.newURL

HashChangeEvent/newURL

所有当前引擎都支持。

Firefox6+Safari5.1+Chrome8+
Opera12.1+Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回现在当前的 会话历史条目URL

oldURL 属性必须返回其初始化的值。它表示事件的上下文信息,特别是从其遍历的 会话历史条目 的 URL。

newURL 属性必须返回其初始化的值。它表示事件的上下文信息,特别是遍历到的 会话历史条目 的 URL。

7.2.7.4 PageSwapEvent 接口
[Exposed=Window]
interface PageSwapEvent : Event {
  constructor(DOMString type, optional PageSwapEventInit eventInitDict = {});
  readonly attribute NavigationActivation? activation;
  readonly attribute ViewTransition? viewTransition;
};

dictionary PageSwapEventInit : EventInit {
  NavigationActivation? activation = null;
  ViewTransition? viewTransition = null;
};
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。

activationviewTransition 属性必须返回其初始化的值。

7.2.7.5 PageRevealEvent 接口
[Exposed=Window]
interface PageRevealEvent : Event {
  constructor(DOMString type, optional PageRevealEventInit eventInitDict = {});
  readonly attribute ViewTransition? viewTransition;
};

dictionary PageRevealEventInit : EventInit {
  ViewTransition? viewTransition = null;
};
event.viewTransition

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

viewTransition 属性必须返回其初始化的值。

7.2.7.6 PageTransitionEvent 接口

PageTransitionEvent/PageTransitionEvent

所有当前引擎都支持。

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

PageTransitionEvent

所有当前引擎都支持。

Firefox1.5+Safari5+Chrome4+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
[Exposed=Window]
interface PageTransitionEvent : Event {
  constructor(DOMString type, optional PageTransitionEventInit eventInitDict = {});

  readonly attribute boolean persisted;
};

dictionary PageTransitionEventInit : EventInit {
  boolean persisted = false;
};
event.persisted

PageTransitionEvent/persisted

所有当前引擎都支持。

Firefox11+Safari5+Chrome4+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android?

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

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

可能导致页面无法保存的内容包括

persisted 属性必须返回其初始化的值。它表示事件的上下文信息。

触发名为 eventName 的页面转换事件Window window 上,并使用布尔值 persisted触发名为 eventName 的事件window 上,使用 PageTransitionEvent,其中 persisted 属性初始化为 persistedcancelable 属性初始化为 true,bubbles 属性初始化为 true,并且设置了 旧版目标覆盖标志

cancelablebubbles 的值毫无意义,因为取消事件不会执行任何操作,并且无法在 Window 对象之外冒泡。出于历史原因,它们被设置为 true。

7.2.7.7 BeforeUnloadEvent 接口

BeforeUnloadEvent

所有当前引擎都支持。

Firefox1.5+Safari7+Chrome30+
Opera?Edge79+
Edge (Legacy)?Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet3.0+Opera Android?
[Exposed=Window]
interface BeforeUnloadEvent : Event {
  attribute DOMString returnValue;
};

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

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

returnValue 属性控制检查卸载是否被取消的过程。创建事件时,必须将该属性设置为空字符串。获取时,必须返回上次设置的值。设置时,必须将属性设置为新值。

出于历史原因,此属性仅为DOMString。除空字符串之外的任何值都将被视为请求用户确认。

7.2.8 NotRestoredReasons 接口

[Exposed=Window]
interface NotRestoredReasonDetails {
  readonly attribute DOMString reason;
  [Default] object toJSON();
};

[Exposed=Window]
interface NotRestoredReasons {
  readonly attribute DOMString? src;
  readonly attribute DOMString? id;
  readonly attribute DOMString? name;
  readonly attribute DOMString? url;
  readonly attribute FrozenArray<NotRestoredReasonDetails>? reasons;
  readonly attribute FrozenArray<NotRestoredReasons>? children;
  [Default] object toJSON();
};
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

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

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

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

  3. 返回notRestoredReasonDetails

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

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

"fetch"
在卸载期间,此Document 启动的提取仍在进行中并被取消,因此页面处于无法存储在后退/前进缓存中的不稳定状态。
"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. 如果 backingStruct原因 为空,则将 notRestoredReasons原因数组 设置为空。

  4. 否则

    1. reasonsArray 为一个空 列表

    2. 对于 backingStruct原因 中的每个 reason

      1. 给定 reasonrealm创建 NotRestoredReasonDetails 对象,并将其 追加reasonsArray

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

  5. 如果 backingStruct子元素 为空,则将 notRestoredReasons子元素数组 设置为空。

  6. 否则

    1. childrenArray 为一个空 列表

    2. 对于 backingStruct子元素 中的每个 child

      1. 给定 childrealm创建 NotRestoredReasons 对象,并将其 追加childrenArray

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

  7. 返回 notRestoredReasons

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

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