1. 基础设施
本规范依赖于现行标准的基础设施标准。[INFRA]
本规范中使用的一些术语定义于 编码、 选择器、受信任类型、Web IDL、XML、 XML 中的命名空间 和 将样式表与 XML 文档关联。 [ENCODING] [SELECTORS4] [TRUSTED-TYPES] [WEBIDL] [XML] [XML-NAMES] [XML-STYLESHEET]
当需要扩展时,可以相应地更新 DOM 标准,或者可以编写一个新标准,该标准可以利用为 适用的规范 提供的可扩展性钩子。
1.1. 树
树 是一个有限的层次树结构。树的顺序是对树的先序、深度优先遍历。
一个 参与 树的对象具有一个父节点,其值可以是 null 或一个对象,并且具有 子节点,它们是由对象组成的 有序 集合。如果对象 A 的父节点是对象 B,则 A 是 B 的一个子节点。
如果一个对象的 父节点为 null,则该对象的根节点是其自身,否则 它的根节点就是 其 父节点的根节点。树的根节点是任何 参与该树且其父节点为 null 的对象。
如果对象A是对象B的子,或者对象A是对象C的子,而C是B的后代,则对象A被称为对象B的后代。
包含后代是指一个对象或其后代之一。
当且仅当B是A的后代时,称对象A为对象B的祖先。
包含祖先是指一个对象或其祖先之一。
当且仅当B和A共享相同的非空父节点时,称对象A为对象B的同胞。
包含同胞是指一个对象或其同胞之一。
如果A和B在同一个树中,并且A在树的顺序中位于B之前,则称对象A先于对象B。
如果A和B在同一个树中,并且A在树的顺序中位于B之后,则称对象A继于对象B。
一个对象的第一个子节点是其第一个子节点,如果它没有子节点,则为 null。
一个对象的最后一个子节点是其最后一个子节点,如果它没有子节点,则为 null。
一个对象的前一个兄弟节点是 其第一个位于其之前的 兄弟节点;如果没有 位于其之前的 兄弟节点,则为 null。
一个对象的后一个兄弟节点是其 第一个位于其之后的 兄弟节点;如果没有位于其之后的 兄弟节点,则为 null。
1.2. 有序集合
有序集合解析器接受一个字符串input,然后执行以下步骤:
-
令inputTokens为在 ASCII 空白字符处分割input的结果。
-
令tokens为一个新的有序集合。
- 返回tokens。
有序集合序列化器接受一个set,并返回使用U+0020 SPACE连接的set的串联结果。
1.3. 选择器
给定字符串 selectors 和 节点 node,作用域匹配选择器字符串 的步骤如下:
-
令 selector 为 解析选择器 selectors 的结果。 [SELECTORS4]
-
如果 selector 返回失败,则 抛出一个 "
SyntaxError"DOMException。 -
返回 selector 与 node 的 根节点 通过 作用域根 node 进行 在树中匹配选择器 的结果。[SELECTORS4]。
不打算支持在选择器中使用命名空间,也不会添加此功能。
1.4. 名称验证
一个字符串是 一个有效的命名空间 前缀,如果其长度至少为 1,且 不包含ASCII 空白字符、U+0000 NULL、U+002F (/) 或 U+003E (>)。
一个字符串是 一个有效的 属性局部名称,如果其长度至少 为 1 且不包含ASCII 空白字符、U+0000 NULL、U+002F (/)、U+003D (=) 或 U+003E (>)。
一个字符串 name 是一个有效的元素局部名称,如果以下步骤返回 true:
-
如果 name 的长度为 0,则返回 false。
-
-
如果 name 包含ASCII 空白字符、U+0000 NULL、U+002F (/) 或 U+003E (>),则 返回 false。
-
返回 true。
-
-
如果 name 的第 0 个码点不是 U+003A (:)、U+005F (_) 或处于 U+0080 至 U+10FFFF(含端点)的范围内,则返回 false。
-
如果 name 后续的码点, 如果存在,不是ASCII 字母、ASCII 数字、 U+002D (-)、U+002E (.)、U+003A (:)、U+005F (_) 或 U+0080 至 U+10FFFF(含端点)范围内的码点, 则 返回 false。
-
返回 true。
此概念用于验证通过 DOM API 构造的元素的局部名称。其目的是允许使用 HTML 解析器能够构造的任何名称(第一个码点是一个ASCII 字母的分支),以及一些其他 可能的名称。对于这些额外的名称,由于历史 原因,ASCII 范围受到限制,但 ASCII 范围之外允许使用任何字符。
以下与 JavaScript 兼容的正则表达式实现了 有效的 元素局部名称:
/^(?:[A-Za-z][^\0\t\n\f\r\u0020/>]*|[:_\u0080-\u{10FFFF}][A-Za-z0-9-.:_\u0080-\u{10FFFF}]*)$/u
一个字符串是一个 有效的文档类型名称 如果它不包含ASCII 空白字符、 U+0000 NULL 或 U+003E (>)。
空字符串是一个有效的文档类型名称。
给定一个 context,要验证并 提取 namespace 和 qualifiedName,执行 以下步骤:
-
如果 namespace 为空字符串,则将其设为 null。
-
令 prefix 为 null。
-
令 localName 为 qualifiedName。
-
如果 qualifiedName 包含 U+003A (:):
-
将 prefix 设为 qualifiedName 中第一个 U+003A (:) 之前的部分。
-
将 localName 设为 qualifiedName 中第一个 U+003A (:) 之后的部分。
-
如果 prefix 不是一个有效的命名空间前缀,则抛出一个 "
InvalidCharacterError"DOMException。
-
-
如果 context 为 "
attribute",且 localName 不是一个 有效的属性局部名称,则抛出一个 "InvalidCharacterError"DOMException。 -
如果 context 为 "
element",且 localName 不是一个 有效的元素局部名称,则抛出一个 "InvalidCharacterError"DOMException。 -
如果 prefix 不为 null 且 namespace 为 null,则抛出一个 "
NamespaceError"DOMException。 -
如果 prefix 为 "
xml",且 namespace 不是 XML 命名空间,则抛出一个 "NamespaceError"DOMException。 -
如果 qualifiedName 或 prefix 为 "
xmlns",且 namespace 不是XMLNS 命名空间,则抛出一个 "NamespaceError"DOMException。 -
如果 namespace 是XMLNS 命名空间,而 qualifiedName 和 prefix 都不是 "
xmlns",则抛出一个 "NamespaceError"DOMException。 -
返回 (namespace, prefix, localName)。
过去,本规范中的多个 API 会对命名空间前缀、属性局部名称、 元素局部名称和文档类型名称执行更严格的验证。这些验证采用了与 多项 XML 相关规范一致的方式。(尽管并未执行这些规范中的 所有规则。)
事实证明,这给 Web 开发者带来了不便,尤其是因为某些 名称可以由 HTML 解析器创建,却无法通过 DOM API 创建。因此,验证规则已 放宽为仅包含上述规则。
2. 事件
2.1. “DOM 事件”简介
在整个 Web 平台中,事件会被分派给对象,以表示某个
事件的发生,例如网络活动或用户交互。这些对象实现了
EventTarget
接口,因此可以添加事件监听器,以观察
事件,方法是调用 addEventListener():
obj. addEventListener( "load" , imgFetched) function imgFetched( ev) { // 非常成功 …}
事件
监听器可以通过
使用
removeEventListener()
方法并传入相同的参数来移除。
或者,事件监听器也可以通过将一个 AbortSignal
传递给
addEventListener()
并调用 abort()
方法(在
拥有该信号的控制器上)来移除。
事件本身也是对象,并且
实现了
Event 接口(或其
派生接口)。在上述示例中,
ev 就是该事件。
ev 会
作为参数传递给
事件
监听器的回调
(通常是如上所示的 JavaScript 函数)。
事件
监听器依据
事件的
type
属性值
(上述示例中的 "load")进行匹配。该
事件的
target
属性值返回
接收该事件的
分派目标对象
(即上面的 obj)。
尽管事件通常由用户代理 分派 以响应用户交互或某项任务的完成,但应用程序也可以自行分派 事件,即 通常所谓的合成事件:
// 添加适当的事件监听器 obj. addEventListener( "cat" , function ( e) { process( e. detail) }) // 创建并分派事件 var event= new CustomEvent( "cat" , { "detail" : { "hazcheeseburger" : true }}) obj. dispatchEvent( event)
除了发出信号外,事件
有时
还用于让应用程序控制某项操作接下来如何进行。例如,在表单提交过程中,
一个
事件的
type
属性值为
"submit",该事件会被
分派。
如果调用这个
事件的
preventDefault()
方法,
表单提交就会终止。希望
借助事件
分派
(即应用程序自行分派的合成事件)
来使用此功能的应用程序,可以利用
dispatchEvent()
方法的返回值:
if ( obj. dispatchEvent( event)) { // 事件未被取消,是时候施展一些魔法了 …}
当一个事件被分派
给某个参与一棵树的对象时
(例如一个元素),它还可以
触达事件
监听器,即位于该对象的
祖先上的监听器。
具体而言,该对象的所有包含自身的祖先上的
事件
监听器,只要其capture 为 true,就会按照
树顺序被调用。接着,
如果事件的 bubbles
为 true,则该对象的所有
包含自身的祖先上的事件监听器,只要其capture 为
false,
就会按照相反的树顺序被调用。
<!doctype html> < html > < head > < title > 乏味的示例</ title > </ head > < body > < p > 你好,< span id = x > 世界</ span > !</ p > < script > function test( e) { debug( e. target, e. currentTarget, e. eventPhase) } document. addEventListener( "hey" , test, { capture: true }) document. body. addEventListener( "hey" , test) var ev= new Event( "hey" , { bubbles: true }) document. getElementById( "x" ). dispatchEvent( ev) </ script > </ body > </ html >
debug 函数将被调用两次。每次事件的
target
属性值都是 span 元素。第一次调用时,
currentTarget
属性值是文档,第二次调用时则是
body 元素。
eventPhase
属性值从
CAPTURING_PHASE
变为 BUBBLING_PHASE。
如果为 span 元素注册了一个事件
监听器,那么
eventPhase
属性值将会
是 AT_TARGET。
2.2. 接口 Event
[Exposed=*]interface {Event (constructor DOMString ,type optional EventInit = {});eventInitDict readonly attribute DOMString type ;readonly attribute EventTarget ?target ;readonly attribute EventTarget ?srcElement ; // 遗留readonly attribute EventTarget ?currentTarget ;sequence <EventTarget >composedPath ();const unsigned short NONE = 0;const unsigned short CAPTURING_PHASE = 1;const unsigned short AT_TARGET = 2;const unsigned short BUBBLING_PHASE = 3;readonly attribute unsigned short eventPhase ;undefined stopPropagation ();attribute boolean cancelBubble ; // .stopPropagation() 的遗留别名undefined stopImmediatePropagation ();readonly attribute boolean bubbles ;readonly attribute boolean cancelable ;attribute boolean returnValue ; // 遗留undefined preventDefault ();readonly attribute boolean defaultPrevented ;readonly attribute boolean composed ; [LegacyUnforgeable ]readonly attribute boolean isTrusted ;readonly attribute DOMHighResTimeStamp timeStamp ;undefined initEvent (DOMString ,type optional boolean =bubbles false ,optional boolean =cancelable false ); // 遗留 };dictionary {EventInit boolean =bubbles false ;boolean =cancelable false ;boolean =composed false ; };
一个 Event 对象
简称为事件。它
用于
表示某件事情已经发生,例如图像已下载完成。
一个潜在事件
目标是 null 或一个 EventTarget
对象。
一个事件具有关联的 目标 (一个 潜在事件 目标)。除非另有说明,否则其值为 null。
一个事件具有关联的 relatedTarget(一个 潜在事件 目标)。除非另有说明,否则其值为 null。
其他规范使用 relatedTarget 来定义
relatedTarget 属性。[UIEVENTS]
一个事件具有关联的 触摸目标列表(一个包含零个或 多个潜在 事件目标的列表)。除非另有说明,否则它是 空列表。
触摸目标列表仅用于定义
TouchEvent
接口及相关接口。[TOUCH-EVENTS]
一个事件具有关联的
路径。一个
路径是一个由事件路径项组成的
列表。一个事件路径项是一个结构体,
由一个调用目标
(一个 EventTarget
对象)、一个
调用目标位于影子树中
(布尔值)、一个
经影子树调整的目标(一个
潜在事件
目标)、一个
relatedTarget(一个
潜在事件
目标)、一个
触摸目标列表(一个由
潜在事件
目标组成的列表)、一个
闭合树的根节点(布尔值),
以及一个闭合树中的插槽(一个
布尔值)组成。一个路径最初是
空列表。
event = new Event(type [, eventInitDict])- 返回一个新的 event,其
type属性值被设置为 type。eventInitDict 参数 允许通过同名的对象成员来设置bubbles和cancelable属性。 event .type- 返回 event 的类型,例如
"
click"、"hashchange" 或 "submit"。 event .target- 返回 event 被分派到的对象(即其 目标)。
event .currentTarget- 返回其事件监听器的回调当前 正在被 调用的对象。
event .composedPath()- 返回 event 的调用目标对象,这些对象位于其
路径中(监听器将在这些对象上
被调用),但不包括任何
节点,如果它们位于影子树中,
且其影子
根节点的
模式为
"
closed",并且无法从 event 的currentTarget访问。 event .eventPhase- 返回事件的
阶段,该阶段为以下值之一:
NONE、CAPTURING_PHASE、AT_TARGET和BUBBLING_PHASE。 event . stopPropagation()- 当事件在树中被分派时,调用此方法可阻止 event 到达当前对象以外的任何对象。
event . stopImmediatePropagation()- 调用此方法可阻止 event 在当前监听器运行结束后 到达任何其他已注册的事件监听器,并且当事件 在树中被分派时,还会阻止 event 到达任何 其他对象。
event .bubbles- 根据 event 的初始化方式返回 true 或 false。如果 event 按照相反的树顺序经过其目标的 祖先, 则返回 true;否则返回 false。
event .cancelable- 根据 event 的初始化方式返回 true 或 false。其返回
值并不总是具有实际意义,但 true 可以表示
event 被分派期间所执行的操作的一部分可以通过调用
preventDefault()方法来取消。 event . preventDefault()- 如果在
cancelable属性值为 true,且正在执行 event 的passive设置为 false 的监听器时调用此方法,则向 导致 event 被分派的操作发出信号,表示该操作需要被取消。 event .defaultPrevented- 如果成功调用了
preventDefault()以表示取消,则返回 true; 否则返回 false。 event .composed- 根据 event 的初始化方式返回 true 或 false。如果
event 会调用位于
ShadowRoot节点之外的监听器,且该节点是其 目标的根节点,则返回 true;否则返回 false。 event .isTrusted- 如果 event 是由用户代理 分派的,则返回 true, 否则返回 false。
event .timeStamp- 返回 event 的时间戳,以相对于 事件发生时刻测量的毫秒数表示。
type 属性必须返回其
初始化时的值。创建事件
时,必须将该属性初始化为空
字符串。
currentTarget 属性必须返回其
初始化时的值。创建事件时,必须将该属性初始化为 null。
composedPath() 方法的步骤如下:
-
令 composedPath 为一个空列表。
-
如果 path 为空,则返回 composedPath。
-
令 currentTarget 为this 的
currentTarget属性值。 -
断言:currentTarget 是一个
EventTarget对象。 -
将 currentTarget 追加到 composedPath。
-
令 currentTargetIndex 为 0。
-
令 currentTargetHiddenSubtreeLevel 为 0。
-
令 index 为 path 的大小减去 1。
-
当 index 大于或等于 0 时:
-
令 currentHiddenLevel 和 maxHiddenLevel 均为 currentTargetHiddenSubtreeLevel。
-
将 index 设为 currentTargetIndex − 1。
-
当 index 大于或等于 0 时:
-
将 currentHiddenLevel 和 maxHiddenLevel 均设为 currentTargetHiddenSubtreeLevel。
-
将 index 设为 currentTargetIndex + 1。
-
当 index 小于 path 的大小时:
-
返回 composedPath。
eventPhase 属性必须返回其
初始化时的值,该值必须是以下值之一:
NONE(数值 0)- 当前未被分派的事件处于此阶段。
CAPTURING_PHASE(数值 1)- 当一个事件被分派给一个参与 树的对象时,在该事件到达 其目标之前,将处于此 阶段。
AT_TARGET(数值 2)- 当一个事件被分派时,在其 目标上将处于此阶段。
BUBBLING_PHASE(数值 3)- 当一个事件被分派给一个参与 树的对象时,在该事件到达 其目标之后,将处于此阶段。
最初,必须将该属性初始化为 NONE。
每个事件都具有关联的 以下标志,这些标志最初均未设置:
- 停止传播标志
- 立即停止传播标志
- 已取消标志
- 处于被动监听器中标志
- 组合标志
- 已初始化标志
- 分派标志
stopPropagation() 方法的步骤是设置
this 的停止传播
标志。
cancelBubble 获取器步骤是:如果
this 的停止传播
标志已设置,则返回 true;否则返回 false。
cancelBubble
设置器步骤是:如果给定值为 true,则设置this 的停止传播标志;
否则不执行任何操作。
stopImmediatePropagation() 方法的步骤
是设置
this 的停止传播
标志以及this
的
立即停止传播标志。
bubbles 和
cancelable 属性必须返回其
初始化时的值。
给定一个事件 event,要设置已取消
标志,如果
event 的 cancelable
属性值为 true,且 event 的
处于被动
监听器中标志未设置,则设置 event 的已取消标志;
否则不执行任何操作。
returnValue 获取器步骤是:如果
this 的已取消标志已设置,
则返回 false;否则返回 true。
returnValue
设置器步骤是:如果给定值为 false,则使用this 设置已取消标志;
否则不执行任何操作。
preventDefault() 方法的步骤是
使用this 设置已取消
标志。
在某些情况下,调用 preventDefault()
不会产生
任何效果。鼓励用户代理在开发者控制台中记录确切原因,以帮助
调试。
defaultPrevented 获取器步骤是:如果
this 的已取消标志已设置,
则返回 true;否则返回 false。
composed 获取器步骤是:如果
this 的组合标志已设置,
则返回 true;否则返回 false。
isTrusted 属性必须返回其
初始化时的值。创建事件
时,必须将该属性初始化为 false。
isTrusted
是一个用于指示
事件是否由用户代理分派
(而不是通过调用
dispatchEvent())的便捷属性。
唯一的遗留例外是 click(),
它会使
用户代理分派一个事件,其 isTrusted
属性被初始化为
false。
timeStamp 属性必须返回其
初始化时的值。
要使用 type、bubbles 和 cancelable 初始化一个 event,请 运行以下步骤:
initEvent(type, bubbles, cancelable)
方法的步骤如下:
initEvent()
与事件
构造函数的功能重复,并且
无法设置 composed。
为了兼容遗留内容,必须支持它。
2.3.
对 Window
接口的传统扩展
partial interface Window { [Replaceable ]readonly attribute (Event or undefined )event ; // legacy };
每个 Window
对象都有一个关联的 当前事件(未定义或一个 Event
对象)。除非另有说明,否则它是未定义的。
event 的 getter 步骤是返回 this 的 当前事件。
强烈建议 Web 开发者依赖传递给事件监听器的 Event
对象,因为这将产生更具可移植性的代码。此属性在 workers 或 worklets 中不可用,并且对于在 shadow trees 中分派的事件是不准确的。
2.4. 接口 CustomEvent
[Exposed=*]interface :CustomEvent Event {(constructor DOMString ,type optional CustomEventInit = {});eventInitDict readonly attribute any detail ;undefined initCustomEvent (DOMString ,type optional boolean =bubbles false ,optional boolean =cancelable false ,optional any =detail null ); // legacy };dictionary :CustomEventInit EventInit {any =detail null ; };
事件 使用 CustomEvent
接口可以用于携带自定义数据。
event = new CustomEvent(type [, eventInitDict])- 其工作方式类似于
Event的构造函数,但 eventInitDict 参数现在还允许设置detail属性。 event .detail- 返回创建 event 时的任何自定义数据。 通常用于合成事件。
detail 属性必须返回它初始化时的值。
initCustomEvent(type, bubbles, cancelable, detail)
方法的步骤如下:
2.5. 构造事件
规范可以为全部或部分
事件定义事件
构造步骤。该算法会接收一个
事件
event 和一个 EventInit
eventInitDict,如内部事件创建步骤中所述。
此构造可供 Event 子类使用,这些子类的
结构比其初始化字典成员与 IDL 属性之间简单的一对一映射
更为复杂。
要
使用 eventInterface 创建事件,
其中 eventInterface 必须是 Event 或
继承自该接口的
接口,并且可以选择性地给定一个领域
realm,运行以下步骤:
-
如果未给定 realm,则将其设为 null。
-
令 dictionary 为将 JavaScript 值 undefined 转换 为 eventInterface 的构造函数所接受的字典类型的结果。 (此字典类型可以是
EventInit或继承自它的 字典。)如果成员是必需的,则此方法不起作用;请参阅 whatwg/dom#600。
-
令 event 为使用 eventInterface、realm、 事件所表示的发生时刻以及 dictionary 运行内部事件 创建步骤的结果。
-
将 event 的
isTrusted属性初始化为 true。 -
返回 event。
创建事件旨在供其他需要 分别创建和分派事件,而不是直接 触发事件的规范使用。它 确保事件的属性被初始化为 正确的默认值。
给定 eventInterface、 realm、time 和 dictionary,内部 事件创建步骤如下:
-
令 event 为使用 eventInterface 创建新对象的结果。如果 realm 不为 null,则使用该领域;否则使用 Web IDL 中定义的默认行为。
截至撰写本文时,Web IDL 尚未定义任何默认行为; 请参阅 whatwg/webidl#135。
-
设置 event 的已初始化标志。
-
将 event 的
timeStamp属性初始化为根据 time 和 event 的 相关全局对象计算得到的相对高精度粗略 时间。 -
对于 dictionary 中的每个 member → value: 如果 event 具有一个属性,且该属性的 标识符为 member,则 将该属性初始化为 value。
-
使用 event 和 dictionary 运行事件构造步骤。
-
返回 event。
2.6. 定义事件接口
通常,在定义一个继承自Event的新接口时,请务必征求WHATWG或W3C WebApps
WG社区的反馈。
CustomEvent接口可以作为起点。然而,不要引入任何init*Event()方法,因为它们与构造函数是冗余的。继承自Event接口的接口中如果包含此类方法,也只是出于历史原因。
2.7. 接口 EventTarget
[Exposed=*]interface {EventTarget constructor ();undefined addEventListener (DOMString ,type EventListener ?,callback optional (AddEventListenerOptions or boolean )= {});options undefined removeEventListener (DOMString ,type EventListener ?,callback optional (EventListenerOptions or boolean )= {});options boolean dispatchEvent (Event ); };event callback interface {EventListener undefined (handleEvent Event ); };event dictionary {EventListenerOptions boolean =capture false ; };dictionary :AddEventListenerOptions EventListenerOptions {boolean ;passive boolean =once false ;AbortSignal ; };signal
一个 EventTarget
对象表示一个目标,当某件事情发生时,可以将事件分派
给该目标。
每个 EventTarget
对象都具有关联的事件监听器列表(一个包含零个或
多个事件
监听器的列表)。它最初是空列表。
一个事件监听器 可用于观察特定的 事件,并由以下部分组成:
- 类型(一个字符串)
- 回调(null 或一个
EventListener对象) - 捕获(一个布尔值,最初为 false)
- 被动(null 或一个布尔值,最初为 null)
- 单次(一个布尔值,最初为 false)
- 信号(null 或一个
AbortSignal对象) - 已移除(用于记录状态的布尔值,最初为 false)
尽管回调是一个 EventListener
对象,但如上所示,事件监听器是一个更广泛的概念。
每个 EventTarget
对象还具有关联的获取父节点算法,
该算法接收一个事件
event,并返回一个 EventTarget
对象。除非
另有规定,否则返回 null。
每个 EventTarget
对象都可以具有关联的
激活行为算法。该
激活行为算法接收一个事件,如
分派
算法中所述。
这是因为用户代理会针对某些
EventTarget
对象(例如
area
元素)执行某些操作,以响应合成的 MouseEvent
事件,其 type
属性为 click。出于 Web 兼容性考虑,无法将其
移除,因此它如今已成为定义某个对象激活行为的正式方式。[HTML]
每个具有
EventTarget
激活行为的对象,还可以
同时具有(而非仅有其中之一)遗留预激活行为算法
和遗留已取消激活行为
算法。
这些算法仅适用于复选框和单选按钮
input
元素,
不得用于其他任何用途。[HTML]
target = new EventTarget();-
创建一个新的
EventTarget对象,开发者可以使用该对象分派和 监听事件。 target . addEventListener(type, callback [, options])-
为
type属性值为 type 的事件追加一个事件监听器。 callback 参数设置在事件被分派时将调用的 回调。options 参数设置监听器专用的选项。为兼容性考虑,该参数可以是一个 布尔值,在这种情况下,该方法的行为与将该值指定为 options 的
capture时完全相同。当 options 的
capture设置为 true 时,会阻止 回调在事件的eventPhase属性值为BUBBLING_PHASE时被调用。 当其为 false(或不存在)时, 回调不会在事件的eventPhase属性值为CAPTURING_PHASE时被调用。 无论哪种情况,只要 事件的eventPhase属性值为AT_TARGET,回调都会被调用。当 options 的
passive设置为 true 时,表示 回调不会通过调用preventDefault()来取消事件。 这用于启用 § 2.8 观察事件监听器中所述的性能优化。当 options 的
once设置为 true 时,表示 回调只会被调用一次,之后 事件监听器将 被移除。如果为 options 的
signal传入一个AbortSignal, 则事件监听器将在信号被中止时移除。 target . removeEventListener(type, callback [, options])target . dispatchEvent(event)-
将合成事件 event 分派给 target,并且如果 event 的
cancelable属性值为 false,或者其preventDefault()方法未被调用,则返回 true;否则返回 false。
要展平 options,运行以下 步骤:
-
如果 options 是一个布尔值,则返回 options。
-
返回 options["
capture"]。
要进一步展平 options,运行以下 步骤:
new EventTarget()
构造函数的步骤是不执行任何操作。
由于其他地方规定的默认值,返回的 EventTarget
的
获取父节点算法
将返回 null,并且它不会具有
激活行为、遗留预激活行为
或遗留已取消激活行为。
将来我们可以允许自定义获取父节点算法。如果这
很有用,请支持议题 #583。目前,所有
由作者创建的 EventTarget
对象
都不参与树结构。
给定事件类型 type 和一个 EventTarget
eventTarget,默认被动
值按以下方式确定:
要添加事件
监听器,给定一个 EventTarget
对象
eventTarget 和一个事件监听器 listener,运行以下步骤:
-
如果 eventTarget 是一个
ServiceWorkerGlobalScope对象,且其 服务工作线程的 脚本资源的 曾被求值标志已设置,并且 listener 的 类型 与任意 服务工作线程事件的type属性值匹配,则应向控制台报告一条警告,指出这 可能无法得到 预期结果。[SERVICE-WORKERS] -
如果 listener 的回调为 null,则返回。
-
如果 listener 的被动值为 null,则将其设为 根据 listener 的类型和 eventTarget 确定的默认 被动值。
-
如果 eventTarget 的事件监听器列表不包含一个 事件监听器,其类型为 listener 的 类型, 回调为 listener 的 回调,且捕获值为 listener 的捕获值,则将 listener 追加 到 eventTarget 的事件 监听器列表。
-
如果 listener 的信号不为 null,则 向其添加以下 中止步骤:
- 使用 eventTarget 和 listener 移除事件监听器。
addEventListener(type, callback, options)
方法的步骤如下:
要移除事件
监听器,给定一个 EventTarget
对象
eventTarget 和一个事件监听器 listener,运行以下步骤:
-
如果 eventTarget 是一个
ServiceWorkerGlobalScope对象,且其 服务工作线程的 待处理事件类型集合 包含 listener 的类型,则应向控制台报告一条警告, 指出这可能无法得到预期结果。[SERVICE-WORKERS] -
将 listener 的已移除设为 true,并 从 eventTarget 的移除 listener,即从其 事件监听器列表中移除。
HTML 需要此算法来定义事件处理器。[HTML]
要移除所有
事件监听器,给定一个 EventTarget
对象
eventTarget:对于 eventTarget 的
事件监听器列表中的每个
listener:
使用
eventTarget 和 listener 移除事件监听器。
HTML 需要此算法来定义 document.open()。[HTML]
removeEventListener(type, callback, options)
方法的步骤如下:
-
令 capture 为展平 options 的结果。
-
如果this 的事件 监听器列表 包含一个 事件监听器,其类型为 type, 回调为 callback,且 捕获值为 capture,则 使用this 和该事件监听器 移除事件监听器。
事件监听器列表不会包含多个具有相同 type、callback 和 capture 的事件监听器,因为添加事件监听器 算法会阻止这种情况。
dispatchEvent(event) 方法的步骤
如下:
-
如果 event 的分派标志已设置,或者其已初始化标志未 设置,则抛出一个 "
InvalidStateError"DOMException。 -
将 event 的
isTrusted属性初始化为 false。
2.8. 观察事件监听器
一般来说,开发者不会期望事件监听器的存在是可观察的。 事件监听器的影响由其回调决定。也就是说, 开发者添加一个无操作的事件监听器时不会期望它有任何副作用。
遗憾的是,某些事件 API 的设计使得要高效实现它们,
就必须观察事件监听器。这可能使监听器的存在
变得可观察,
因为即使是空监听器,也可能对应用程序的行为产生显著的性能影响。
例如,可用于阻止异步滚动的触摸事件和滚轮事件。在某些情况下,
可以通过将事件标记为cancelable,
但仅在存在
至少一个非passive
监听器时才这样做。例如,
非passive
TouchEvent
监听器必须阻止滚动,但如果所有
监听器都是 passive,
则可以允许滚动开始
并行进行,方法是使 TouchEvent
不可取消(因此对
preventDefault()
的调用会被忽略)。因此,分派事件的代码能够观察到
非passive
监听器的缺失,并据此清除正在分派的事件的 cancelable
属性。
理想情况下,任何新的事件API都应定义为不需要此属性。(请使用whatwg/dom进行讨论。)
要获取遗留的Service
Worker获取事件侦听器回调,给定一个ServiceWorkerGlobalScopeglobal,请运行以下步骤。这些步骤将返回一个EventListener对象的列表。
2.9. 分发事件
要向一个
事件 event 的
一个
EventTarget
对象 target 分派事件,并可选地提供 legacy target override flag 和
legacyOutputDidListenersThrowFlag:
-
设置 event 的分派标志。
-
如果未给定 legacy target override flag,则令 targetOverride 为 target;否则为 target 的关联的
Document。 [HTML]legacy target override flag 仅由 HTML 使用,且仅当 target 是一个
Window对象时使用。 -
令 activationTarget 为 null。
-
令 relatedTarget 为以 target 为参照,对 event 的 relatedTarget 进行重定向的结果。
-
令 clearTargets 为 false。
-
如果 target 不等于 relatedTarget,或者 target 是 event 的 relatedTarget:
-
令 touchTargets 为一个新的列表。
-
对于 event 的触摸目标列表中的每个 touchTarget:将以 target 为参照 重定向 touchTarget 的结果追加到 touchTargets。
-
使用 event、target、 targetOverride、relatedTarget、touchTargets 和 false 追加到事件路径。
-
如果 event 是一个
MouseEvent对象, 且 event 的type属性为 "click",则令 isActivationEvent 为 true;否则为 false。 -
如果 isActivationEvent 为 true,且 target 具有 激活行为,则将 activationTarget 设为 target。
-
令 slotInClosedTree 为 false。
-
令 parent 为使用 event 调用 target 的获取 父节点 算法的结果。
-
当 parent 不为 null 时:
-
如果 slottable 不为 null:
-
令 relatedTarget 为以 parent 为参照,对 event 的 relatedTarget 进行重定向的结果。
-
令 touchTargets 为一个新的列表。
-
对于 event 的 触摸目标列表中的每个 touchTarget: 将以 parent 为参照,对 touchTarget 进行重定向 的结果追加到 touchTargets。
-
如果 parent 是一个
Window对象,或者 parent 是一个节点, 且 target 的根节点是 parent 的包含影子树且包含自身的 祖先: -
否则,如果 parent 为 relatedTarget,则将 parent 设为 null。
-
否则:
-
如果 parent 不为 null,则将 parent 设为 使用 event 调用 parent 的获取父节点算法的结果。
-
将 slotInClosedTree 设为 false。
-
-
令 clearTargetsItem 为 event 的 路径中, 经影子树调整的目标不为 null 的最后一个事件路径项。
-
如果 clearTargetsItem 的经影子树调整的目标、 clearTargetsItem 的relatedTarget,或 clearTargetsItem 的触摸 目标列表中的一个
EventTarget对象是一个节点, 且其根节点是一个影子根节点:则将 clearTargets 设为 true。 -
如果 activationTarget 不为 null,且 activationTarget 具有 遗留预激活 行为,则运行 activationTarget 的 遗留预激活 行为。
-
-
如果 item 的经影子树调整的目标 不为 null,则 将 event 的
eventPhase属性设为AT_TARGET。 -
否则,将 event 的
eventPhase属性设为CAPTURING_PHASE。 -
使用 item、event、"
capturing", 以及给定的 legacyOutputDidListenersThrowFlag(如果提供), 执行调用。
-
-
-
如果 item 的经影子树调整的目标 不为 null,则 将 event 的
eventPhase属性设为AT_TARGET。 -
否则:
-
将 event 的
eventPhase属性设为BUBBLING_PHASE。
-
使用 item、event、"
bubbling", 以及给定的 legacyOutputDidListenersThrowFlag(如果提供), 执行调用。
-
-
-
将 event 的
eventPhase属性设为NONE。 -
将 event 的
currentTarget属性设为 null。 -
将 event 的路径设为空列表。
-
如果 clearTargets 为 true:
-
将 event 的目标设为 null。
-
将 event 的relatedTarget 设为 null。
-
将 event 的触摸目标列表设为空列表。
-
-
如果 activationTarget 不为 null:
-
否则,如果 activationTarget 具有 遗留已取消激活 行为,则运行 activationTarget 的遗留已取消激活 行为。
-
如果 event 的已取消标志已设置,则返回 false;否则返回 true。
要追加到
事件路径,给定一个
事件 event、
一个 EventTarget
对象 invocationTarget、一个
潜在
事件目标 shadowAdjustedTarget、一个潜在事件目标
relatedTarget、一个由潜在事件目标组成的列表
touchTargets,以及一个布尔值 slotInClosedTree:
-
令 invocationTargetInShadowTree 为 false。
-
如果 invocationTarget 是一个节点,且其根节点是一个 影子 根节点,则将 invocationTargetInShadowTree 设为 true。
-
令 rootOfClosedTree 为 false。
-
如果 invocationTarget 是一个影子根节点,且其模式 为 "
closed",则将 rootOfClosedTree 设为 true。 -
向 event 的路径中追加一个新的事件路径项,其 调用目标为 invocationTarget, 调用目标位于影子树中 为 invocationTargetInShadowTree, 经影子树调整的目标为 shadowAdjustedTarget, relatedTarget 为 relatedTarget, 触摸目标列表为 touchTargets, 闭合树的根节点为 rootOfClosedTree,且 闭合树中的插槽为 slotInClosedTree。
要调用,给定一个事件路径项 pathItem、一个事件 event、一个字符串 phase,以及可选的 legacyOutputDidListenersThrowFlag:
-
令 targetItem 为 pathItem。
-
当 targetItem 的经影子树调整的目标为 null 时:将 targetItem 设为 event 的 路径中位于 targetItem 之前的事件路径项。
-
将 event 的relatedTarget 设为 pathItem 的 relatedTarget。
-
如果 event 的停止传播标志已设置,则返回。
-
将 event 的
currentTarget属性初始化为 pathItem 的 调用目标。 -
令 listeners 为 event 的
currentTarget属性值的事件监听器列表的克隆。 -
令 invocationTargetInShadowTree 为 pathItem 的 调用目标位于影子树中。
-
令 found 为使用 event、 listeners、phase、invocationTargetInShadowTree 和 可选的 legacyOutputDidListenersThrowFlag 运行内部调用的结果。
-
如果 found 为 false,且 event 的
isTrusted属性为 true:-
令 originalEventType 为 event 的
type属性值。 -
如果 event 的
type属性值与下表第一列中的任一字符串匹配, 则将 event 的type属性值设为 同一行第二列中的字符串;否则返回。事件类型 遗留事件类型 " animationend"" webkitAnimationEnd"" animationiteration"" webkitAnimationIteration"" animationstart"" webkitAnimationStart"" transitionend"" webkitTransitionEnd" -
使用 event、listeners、phase、 invocationTargetInShadowTree 和 可选的 legacyOutputDidListenersThrowFlag 执行内部调用。
-
将 event 的
type属性值设为 originalEventType。
-
要内部调用,给定一个 事件 event、一个由 事件 监听器组成的列表 listeners、一个 字符串 phase、一个布尔值 invocationTargetInShadowTree,以及可选的 legacyOutputDidListenersThrowFlag:
-
令 found 为 false。
-
对于 listeners 中每个 listener,其 已移除值为 false:
-
将 found 设为 true。
-
如果 listener 的单次值为 true,则 使用 event 的
currentTarget属性值和 listener 移除事件监听器。 -
令 targetGlobal 为 event 的
currentTarget的 节点文档的相关全局对象,如果 event 的currentTarget是一个节点; 否则为 event 的currentTarget的 相关全局对象。 -
如果 targetGlobal 或 listenerGlobal 是一个
Window对象,且其 关联的Document不是完全活动的,则 继续。 -
令 currentEvent 为 undefined。
-
如果 listenerGlobal 是一个
Window对象: -
如果 listener 的被动值为 true,则设置 event 的处于被动监听器中标志。
-
如果 listenerGlobal 是一个
Window对象,则 使用 event 和 listener 记录事件 监听器的计时信息。 -
使用 listener 的 回调、"
handleEvent"、« event » 和 event 的currentTarget属性值,调用用户对象的操作。如果这抛出异常 exception:-
如果给定了 legacyOutputDidListenersThrowFlag,则设置它。
legacyOutputDidListenersThrowFlag 仅 由 Indexed Database API 使用。[INDEXEDDB]
-
取消设置 event 的处于被动监听器中标志。
-
如果 listenerGlobal 是一个
Window对象,则将 listenerGlobal 的 当前事件设为 currentEvent。
-
返回 found。
2.10. 触发事件
要在target上触发事件,事件名为e,可选地使用eventConstructor,并描述如何初始化IDL属性,以及legacy target override flag,请执行以下步骤:
-
令 recordingTimingAsTask 为调用 在需要时开始记录任务时间 并传入 target 的 相关设置对象所得到的结果。
-
如果未给定 eventConstructor,则令 eventConstructor 为
Event。 -
将 event 的
type属性初始化为 e。 -
按照调用此算法时的描述,初始化 event 的所有其他 IDL 属性。
这也允许将
isTrusted属性设置为 false。 -
令 result 为在 target 上分发 event 的结果, 并在设置了 legacy target override flag 时将其设置。
-
如果 recordingTimingAsTask 为 true:
-
返回 result。
在 DOM 的语境中,Fire 是 创建、 初始化以及分派一个事件的简称。 触发事件使 该过程更容易被写下来。
如果该事件需要初始化其
bubbles
或 cancelable
属性,
可以写成“在 target 上触发事件,其名称为 submit,
并将其
cancelable
属性初始化为 true”。
或者,当需要自定义构造函数时,“在
target 上触发事件,其名称为 click,并使用 MouseEvent,
将其 detail
属性初始化为 1”。
有时返回值很重要:
-
令 doAction 为在 target 上触发事件,其名称为
like的结果。 -
如果 doAction 为 true,则 …
2.11. 行为与发生
一个事件表示一次
发生,而不是一个动作。换句话说,它
表示来自算法的通知,并可用于影响该算法未来的执行路径
(例如,通过调用 preventDefault())。
事件不得被
用作会导致某个算法开始运行的动作或发起者。那不是
它们的用途。
这里特别指出这一点,是因为 DOM 以前的 迭代版本中有一个与事件关联的“默认动作”概念, 这让人们产生了完全错误的想法。事件不表示或导致动作,它们 只能用于影响一个正在进行的动作。
3. 中止正在进行的活动
尽管 promise 没有内置的中止机制,但许多使用它们的 API 都需要中止语义。AbortController
旨在通过提供一个 abort()
方法来支持这些要求,该方法可以切换相应 AbortSignal
对象的状态。希望支持中止的 API 可以接受一个 AbortSignal
对象,并使用其状态来确定如何继续。
鼓励依赖 AbortController
的 API 通过使用 AbortSignal
的中止原因来拒绝任何未解决的 promise,从而响应 abort()。
一个假设的 doAmazingness({ ... }) 方法可以接受一个 AbortSignal
对象
以支持如下所示的中止操作:
const controller = new AbortController();
const signal = controller. signal;
startSpinner();
doAmazingness({ ..., signal })
. then( result => ...)
. catch ( err => {
if ( err. name == 'AbortError' ) return ;
showUserErrorMessage();
})
. then(() => stopSpinner());
// …
controller. abort();
doAmazingness 可以按如下方式实现:
function doAmazingness({ signal}) {
return new Promise(( resolve, reject) => {
signal. throwIfAborted();
// 开始执行精彩操作,并在完成时调用 resolve(result)。
// 但同时,还要监听信号:
signal. addEventListener( 'abort' , () => {
// 停止执行精彩操作,然后:
reject( signal. reason);
});
});
}
不返回promise的API可以选择以类似的方式做出反应,或者选择完全不展示AbortSignal的中止原因。addEventListener()就是一个适合后者的API例子。
需要更精细控制的API可以根据需要扩展AbortController和AbortSignal对象。
3.1.
接口 AbortController
[Exposed=*]interface {AbortController constructor (); [SameObject ]readonly attribute AbortSignal signal ;undefined abort (optional any ); };reason
controller = new AbortController()- 返回一个新的 controller,其
signal被设置为一个新 创建的AbortSignal对象。 controller . signal- 返回与此对象关联的
AbortSignal对象。 controller . abort(reason)- 调用此方法会将 reason 存储在此对象的
AbortSignal的 中止 原因中,并向所有观察者发出信号,表明关联的活动应当 中止。如果 reason 为 undefined,则会存储一个 "AbortError"DOMException对象。
一个 AbortController
对象具有关联的信号(一个
AbortSignal
对象)。
new AbortController()
构造函数的步骤如下:
-
令 signal 为一个新的
AbortSignal对象。
要在一个 AbortController
controller 上发出中止信号,并可选地给定 reason,则
使用 reason(如果给定),在 controller 的信号上发出中止信号。
3.2. 接口AbortSignal
[Exposed=*]interface :AbortSignal EventTarget { [NewObject ]static AbortSignal abort (optional any ); [reason Exposed =(Window ,Worker ),NewObject ]static AbortSignal timeout ([EnforceRange ]unsigned long long ); [milliseconds NewObject ]static AbortSignal _any (sequence <AbortSignal >);signals readonly attribute boolean aborted ;readonly attribute any reason ;undefined throwIfAborted ();attribute EventHandler onabort ; };
AbortSignal . abort(reason)- 返回一个
AbortSignal实例,其中止原因被设为 reason(如果不为 undefined);否则设为一个 "AbortError"DOMException。 AbortSignal . any(signals)- 返回一个
AbortSignal实例,当 signals 中任意一个信号被 中止时,该实例也会中止。其中止原因将设为 signals 中 导致其被中止的那个信号的中止原因。 AbortSignal . timeout(milliseconds)- 返回一个
AbortSignal实例,该实例将在 milliseconds 毫秒后中止。其中止原因将设为一个 "TimeoutError"DOMException。 signal . aborted- 如果 signal 的
AbortController已发出中止信号,则返回 true;否则返回 false。 signal . reason- 返回 signal 的中止原因。
signal . throwIfAborted()- 如果 signal 的
AbortController已发出中止信号,则抛出 signal 的中止原因; 否则不执行任何操作。
一个 AbortSignal
对象具有关联的中止原因(一个
JavaScript 值),其初始值为 undefined。
一个 AbortSignal
对象具有关联的中止算法(一个
由该对象被中止时需要执行的算法组成的
集合),
其初始值为空。
中止算法使具有复杂
要求的 API 能够以合理的方式响应 abort()。
例如,给定 API 的
中止
原因可能需要传播到跨线程环境,例如
服务工作线程。
一个 AbortSignal
对象具有一个依赖标志(一个布尔值),其
初始值为 false。
一个 AbortSignal
对象具有关联的源信号(一个由
AbortSignal
对象组成的弱集合,该对象的
中止状态依赖于这些对象),
其初始值为空。
一个 AbortSignal
对象具有关联的依赖信号(一个由
AbortSignal
对象组成的弱集合,这些对象的
中止状态依赖于该对象),
其初始值为空。
静态abort(reason) 方法的步骤
如下:
-
令 signal 为一个新的
AbortSignal对象。 -
如果给定了 reason,则将 signal 的中止原因设为 reason; 否则设为一个新的 "
AbortError"DOMException。 - 返回 signal。
静态timeout(milliseconds) 方法的
步骤如下:
-
令 signal 为一个新的
AbortSignal对象。 -
令 global 为 signal 的相关全局对象。
-
给定 global、 "
AbortSignal-timeout"、milliseconds 和以下步骤, 在超时后运行步骤:-
给定 global,在计时器任务源上排入一个全局任务,以 使用 signal 和一个新的 "
TimeoutError"DOMException发出中止信号。
在此超时期间,如果 signal 为其
abort事件注册了任何事件监听器,则必须存在一个从 global 到 signal 的强引用。 -
-
返回 signal。
静态any(signals) 方法的
步骤是返回使用 AbortSignal
和当前领域,从 signals 创建依赖中止信号的结果。
aborted 获取器步骤是:如果this
已被中止,则返回 true;
否则返回 false。
throwIfAborted() 方法的步骤是:如果 this 已
中止
原因,且 this 已中止,则抛出该原因。
此方法主要适用于以下情况:接受 AbortSignal
的函数
希望在特定检查点抛出异常(或
返回一个被拒绝的 promise),而不是将 AbortSignal
传递给其他方法。例如,以下函数允许在每次尝试
轮询某个条件之间执行中止操作。即使
实际的异步操作(即 )不
接受 AbortSignal,这也提供了中止轮询过程的机会。
async function waitForCondition( func, targetValue, { signal} = {}) { while ( true ) { signal? . throwIfAborted(); const result= await func(); if ( result=== targetValue) { return ; } } }
onabort 属性是
onabort
事件处理器的事件处理器 IDL 属性,其事件处理器事件类型为
abort。
对 AbortSignal
对象的更改代表相应
AbortController
对象的意愿,但观察该 AbortSignal
对象的 API 可以选择忽略
这些更改。例如,当操作已经完成时。
一个 AbortSignal
对象在以下情况下被视为已中止:其
中止
原因不为 undefined。
要向一个 AbortSignal
对象 signal 添加一个算法 algorithm:
要从一个 AbortSignal
signal 中移除一个算法 algorithm,则将 algorithm 从
signal 的中止算法中移除。
要发出中止信号,给定一个 AbortSignal
对象 signal 和
一个可选的 reason:
-
如果 signal 已被中止,则返回。
-
如果给定了 reason,则将 signal 的中止原因设为 reason; 否则 设为一个新的 "
AbortError"DOMException。 -
令 dependentSignalsToAbort 为一个新的列表。
-
为 signal 运行 中止步骤。
要为一个 AbortSignal
signal 运行中止
步骤:
要创建一个
依赖中止信号,给定一个由 AbortSignal
对象组成的列表
signals,使用 signalInterface,其必须是 AbortSignal
或一个
继承自它的接口,以及一个 realm:
3.2.1. 垃圾回收
一个未中止的依赖的
AbortSignal
对象,当其源信号列表非空并且它已为其 abort
事件注册了事件监听器或者其中止算法列表非空时,不能被垃圾回收。
3.3.
在 API 中使用 AbortController
和 AbortSignal
对象
任何使用 promises 表示可以中止操作的 Web 平台 API 必须遵循以下规则:
- 通过
signal字典成员接受AbortSignal对象。 - 通过使用
AbortSignal对象的中止原因来拒绝 promise,从而传达操作已中止。 - 如果
AbortSignal已经中止,则立即拒绝,否则: - 使用中止算法机制来观察
AbortSignal对象的更改,并以不导致与其他观察者冲突的方式执行此操作。
返回 promise 的方法 doAmazingness(options)
的步骤可以如下:
-
令 p 为一个新的 promise。
-
如果 options["
signal"] 存在: -
运行以下步骤,采用并行方式:
-
返回 p。
不使用 promises 的 API 仍应尽可能遵循上述规则。
4. 节点
4.1. “DOM”简介
在其原始意义上,“DOM”是一个用于访问和操作文档(特别是HTML和XML文档)的API。在本规范中,术语“文档”用于任何基于标记的资源,从简短的静态文档到包含丰富多媒体的长篇文章或报告,以及功能齐全的交互式应用程序。
每个这样的文档都表示为一个节点树。树中的一些节点可以有子节点,而其他的总是叶子节点。
为了说明这一点,考虑以下HTML文档:
<!DOCTYPE html> < html class = e > < head >< title > Aliens?</ title ></ head > < body > Why yes.</ body > </ html >
它表示如下:
请注意,由于HTML解析的神奇之处,并非所有ASCII空白字符都被转化为Text节点,但总体概念是清晰的。标记进入,树形节点输出。
可以使用非常棒的Live DOM Viewer来更详细地探索这个问题。
4.2. 节点树
节点是实现了实现Node的对象。节点参与一个称为节点树的树。
实际上,你会处理更具体的对象。
实现
Node 的对象还会实现
一个继承接口:Document、
DocumentType、
DocumentFragment、
Element、
CharacterData
或 Attr。
实现 DocumentFragment
的对象有时会实现 ShadowRoot。
实现 Element 的对象
通常还会实现一个继承接口,例如
HTMLAnchorElement。
实现 CharacterData
的对象还会实现一个继承接口:Text、
ProcessingInstruction
或 Comment。
实现 Text 的对象有时会实现
CDATASection。
因此,每个 节点的 主接口是以下之一:Document、
DocumentType、
DocumentFragment、
ShadowRoot、
Element 或
Element
的继承接口、
Attr、Text、CDATASection、
ProcessingInstruction
或 Comment。
为简洁起见,本规范将实现 Node 和一个
继承接口 NodeInterface 的对象,称为
NodeInterface 节点。
节点树受到如下约束, 表示为一个 节点与其潜在子节点之间的关系:
Document-
按树序:
-
零个或多个
ProcessingInstruction或Comment节点。 -
可选的一个
DocumentType节点。 -
零个或多个
ProcessingInstruction或Comment节点。 -
零个或多个
ProcessingInstruction或Comment节点。
-
DocumentFragmentElement-
零个或多个
Element或CharacterData节点。 DocumentTypeCharacterDataAttr-
没有子节点。
Attr 节点由于历史
原因参与一棵树;它们绝不会有(非空的)父节点或任何子节点,因此
独自处于一棵树中。
-
如果 node 是一个
DocumentType或Attr节点,则返回 0。 -
如果 node 是一个
CharacterData节点,则返回 node 的 数据的长度。 -
返回 node 的子节点的数量。
4.2.1. 文档树
一个文档的文档元素是 一个元素, 如果存在,其父节点是 该文档;否则为 null。
如果一个节点位于文档中,那么它位于文档树中。 术语位于 文档中不再应当使用。它表示 使用该术语的标准尚未更新,以考虑影子树。
4.2.2. 影子树
影子根总是通过其宿主附加到另一个节点树。因此,影子树永远不会是孤立的。影子根的宿主的节点树有时被称为光树。
当一个节点的包含影子的根是一个文档时,该节点被认为是已连接的。
4.2.2.1. 插槽
一个插槽有一个关联的名称(一个字符串)。除非另有说明,否则它是空字符串。
-
如果element是一个插槽,localName是
name,且namespace为空:
一个插槽是一个影子树中的第一个,在树顺序中,其名称为空字符串的插槽,有时被称为“默认插槽”。
一个插槽有一个关联的分配的节点(一个可插槽对象的列表)。除非另有说明,否则它是空的。
4.2.2.2. 可插槽对象
一个可插槽对象有一个关联的名称(一个字符串)。除非另有说明,否则它是空字符串。
-
如果localName是
slot且namespace为空:
字母A 可插槽元素有一个关联的已分配插槽(null或插槽)。 除非另有说明,否则它为null。字母A 可插槽元素是已分配的,如果它的已分配插槽非null。
一个可插槽对象有一个关联的手动插槽分配(null或插槽)。除非另有说明,否则它是null。
一个可插槽对象的手动插槽分配可以使用对插槽的弱引用来实现,因为这个变量不能直接从脚本访问。
4.2.2.3. 查找插槽和可插槽对象
要查找插槽,对于给定的可插入对象 slottable 和一个可选的布尔值 open(默认为 false):
要查找可插入对象,对于给定的插槽 slot:
要查找扁平化可插入对象,对于给定的插槽 slot:
-
设 result 为 « »。
-
设 slottables 为给定 slot 查找可插入对象的结果。
-
对于 slottables 中的每个 node:
-
-
设 temporaryResult 为给定 node 查找扁平化可插入对象的结果。
-
将 temporaryResult 中的每个可插入对象按顺序追加到 result。
-
-
否则,将 node 追加到 result。
-
-
返回 result。
4.2.2.4. 分配可插槽对象和插槽
要为插槽 slot 分配可插入对象:
4.2.2.5. 发出插槽变更信号
每个相同来源窗口代理都有一个信号插槽(集合中的一部分插槽),其初始值为空。[HTML]
要为一个插槽 slot 发出插槽更改信号:
4.2.3. 变异算法
给定一个 节点 node、一个节点 parent、 null 或一个 节点 child,以及一个由列表中的节点 childrenToExclude 组成的确保预插入有效性:
-
如果 parent 不是一个
Document、DocumentFragment, 或Element节点,则抛出一个 "HierarchyRequestError"DOMException。 -
如果 node 是 parent 的含宿主的包含性 祖先,则 抛出一个 "
HierarchyRequestError"DOMException。 -
如果 child 非 null 且其父节点不是 parent, 则抛出一个 "
NotFoundError"DOMException。 -
如果 node 不是一个
DocumentFragment、DocumentType、Element, 或CharacterData节点,则抛出一个 "HierarchyRequestError"DOMException。 -
如果 parent 不是一个文档:
-
如果 node 是一个文档类型,则抛出 一个 "
HierarchyRequestError"DOMException。 -
返回。
-
-
如果 node 是一个
Text节点,则抛出一个 "HierarchyRequestError"DOMException。 -
如果 node 是一个
CharacterData节点,则返回。 -
如果 node 是一个
DocumentFragment节点:-
如果 node 有多个元素子节点,或者有一个
Text节点子节点,则抛出 一个 "HierarchyRequestError"DOMException。
-
-
如果 node 是一个
DocumentFragment或Element节点:-
如果以下任一条件为真:
-
返回。
-
-
如果以下任一条件为真:
规范可以为全部或部分节点定义 插入 步骤。如下面的插入算法 所示,该算法会被传入 insertedNode。这些步骤不得修改 insertedNode 参与的节点树、创建浏览上下文、 触发事件,或 以其他方式执行 JavaScript。不过,这些步骤可以 将任务入队,以异步执行这些操作。
虽然插入步骤不能执行 JavaScript(以及其他一些 操作),但它们确实会产生脚本可观察到的后果。考虑下面的示例:
const h1 = document. querySelector( 'h1' );
const fragment = new DocumentFragment();
const script = fragment. appendChild( document. createElement( 'script' ));
const style = fragment. appendChild( document. createElement( 'style' ));
script. innerText= 'console.log(getComputedStyle(h1).color)' ; // 输出 'rgb(255, 0, 0)'
style. innerText = 'h1 {color: rgb(255, 0, 0);}' ;
document. body. append( fragment);
上面示例中的脚本输出 ,因为
以下操作按顺序发生:
规范还可以为全部或部分 节点定义 连接后步骤。如下面的 插入 算法所示,该算法会被传入 connectedNode。
连接后步骤的目的是为 节点提供机会,以执行任何 与连接相关的操作,这些操作可以修改 connectedNode 参与的节点树、 创建浏览上下文, 或以其他方式执行 JavaScript。这些步骤允许一批节点相对于脚本 原子地插入, 所有主要副作用都在批量插入到节点树完成之后发生。这确保 所有待处理的节点 树插入在更多插入发生之前完全完成。
要将一个插入节点 node 到 一个 节点 parent 中,在 null 或一个节点 child 之前,并带有一个 可选布尔值 suppressObservers(默认为 false):
-
如果 node 是一个
DocumentFragment节点,则令 nodes 为 node 的子节点;否则为 « node »。 -
令 count 为 nodes 的大小。
-
如果 count 为 0,则返回。
-
如果 node 是一个
DocumentFragment节点:-
将其子节点移除,并将 suppressObservers 设置为 true。
-
为 node 将树突变记录入队,并使用 « »、nodes、null 和 null。
此步骤有意不考虑 suppressObservers。
-
-
如果 child 非 null:
-
如果 child 为 null,则令 previousSibling 为 parent 的最后一个子节点;否则为 child 的前一个 同胞节点。
-
对于 nodes 中的每个 node,按树顺序:
-
如果 parent 是一个影子宿主,其影子根的 插槽分配为 "
named", 且 node 是一个 可插槽项,则为 node 分配一个插槽。 -
如果 parent 的根是一个影子根,并且 parent 是一个插槽,其已分配节点是 空列表, 则为 parent 运行发出插槽变更信号。
-
对于 node 的每个影子包含的 包含性后代 inclusiveDescendant,按影子包含树顺序:
-
使用 inclusiveDescendant 运行插入步骤。
-
如果 inclusiveDescendant 是一个元素,且 inclusiveDescendant 的自定义元素注册表非 null:
-
如果 inclusiveDescendant 的自定义元素 注册表的 is scoped 为 true,则将 inclusiveDescendant 的节点文档追加到 inclusiveDescendant 的自定义元素 注册表的 作用域文档集合中。
-
如果 inclusiveDescendant 是自定义的,则 使用 inclusiveDescendant、回调名称 "
connectedCallback" 和 « » 将自定义元素回调反应 入队。 -
否则,尝试升级 inclusiveDescendant。
如果这成功升级了 inclusiveDescendant,则其
connectedCallback会在 升级元素 算法期间自动入队。
-
-
否则,如果 inclusiveDescendant 是一个影子 根, inclusiveDescendant 的自定义元素注册表 非 null,且 inclusiveDescendant 的自定义元素 注册表的 is scoped 为 true,则将 inclusiveDescendant 的节点 文档追加到 inclusiveDescendant 的自定义元素 注册表的 作用域文档集合中。
-
-
如果 suppressObservers 为 false,则为 parent 将树 突变记录入队,并使用 nodes、« »、previousSibling 和 child。
-
为 parent 运行子节点变更步骤。
-
令 staticNodeList 为一个节点列表,初始为 « »。
我们会在对其中任何一个节点调用 连接后步骤之前收集所有节点, 而不是在 遍历节点树时调用 连接后步骤。这是因为 连接后步骤可以修改 树的结构,使实时遍历变得不安全, 并可能导致同一个 节点的 连接后步骤被调用 多次。
-
对于 nodes 中的每个 node,按树顺序:
-
对于 node 的每个影子包含的 包含性后代 inclusiveDescendant,按影子包含树顺序: 将 inclusiveDescendant 追加到 staticNodeList。
-
规范可以为全部或部分节点定义 移动步骤。 如下面的移动算法所示,该 算法会被传入一个节点 movedNode、一个布尔值 isSubtreeRoot,以及一个节点 oldAncestor。 与 插入 步骤一样,这些步骤不得修改 movedNode 参与的节点树、创建浏览上下文、 触发事件,或 以其他方式执行 JavaScript。不过,这些步骤可以将任务入队, 以异步执行这些操作。
要将一个移动节点 node 到 一个节点 newParent 中,在 null 或一个节点 child 之前:
-
如果 newParent 的影子包含根与 node 的影子包含根不同,则抛出一个 "
HierarchyRequestError"DOMException。 -
如果 node 是 newParent 的含宿主的包含性 祖先, 则抛出一个 "
HierarchyRequestError"DOMException。 -
如果 child 非 null 且其父节点不是 newParent, 则抛出一个 "
NotFoundError"DOMException。 -
如果 node 不是一个
Element或一个CharacterData节点,则 抛出一个 "HierarchyRequestError"DOMException。 -
如果 node 是一个
Text节点,且 newParent 是一个 文档, 则抛出一个 "HierarchyRequestError"DOMException。 -
如果 newParent 是一个文档,node 是一个
Element节点,并且 newParent 有一个元素 子节点、 child 是一个文档类型,或者 child 非 null 且有一个 文档类型跟随 child,则抛出一个 "HierarchyRequestError"DOMException。 -
令 oldParent 为 node 的父节点。
-
断言:oldParent 非 null。
-
给定 node,运行实时范围预移除步骤。
-
对于每个
NodeIterator对象 iterator,如果其 根的节点文档是 node 的 节点 文档:给定 node 和 iterator,运行NodeIterator预移除步骤。 -
令 oldPreviousSibling 为 node 的前一个 同胞节点。
-
令 oldNextSibling 为 node 的下一个同胞节点。
-
如果 oldParent 的根是一个影子根,并且 oldParent 是一个插槽,其已分配节点 为空,则为 oldParent 运行发出插槽变更信号。
-
添加临时注册观察器,参数为 node 和 oldParent。
-
如果 child 非 null:
-
如果 child 非 null,则令 newPreviousSibling 为 child 的前一个 同胞节点;否则为 newParent 的最后一个子节点。
-
如果 newParent 是一个影子宿主,其影子根的 插槽分配为 "
named",且 node 是一个 可插槽项, 则为 node 分配一个插槽。 -
如果 newParent 的根是一个影子根,并且 newParent 是一个插槽,其已分配节点 为空,则为 newParent 运行发出插槽变更信号。
-
对于 node 的每个影子包含的包含性 后代 inclusiveDescendant,按影子包含树顺序:
-
如果 inclusiveDescendant 是 node,则令 isSubtreeRoot 为 true;否则为 false。
-
使用 inclusiveDescendant、isSubtreeRoot 和 oldParent 运行移动步骤。
由于移动算法是一个不同于 插入和移除的独立原语,因此它 不会为 inclusiveDescendant 调用插入步骤 或移除步骤。
-
如果 inclusiveDescendant 是自定义的,且 newParent 已 连接,则使用 inclusiveDescendant、回调名称 "
connectedMoveCallback" 和 « » 将自定义元素 回调反应入队。
-
-
为 oldParent 将树突变记录入队,并使用 « »、« node »、 oldPreviousSibling 和 oldNextSibling。
-
为 newParent 将树突变记录入队,并使用 « node »、« »、 newPreviousSibling 和 child。
要在一个节点 parent 内,用一个节点 node 替换一个节点 child:
-
给定 node、parent、 child 和 « child »,确保预插入有效性。
-
令 referenceChild 为 child 的下一个同胞节点。
-
如果 referenceChild 是 node,则将 referenceChild 设置为 node 的下一个同胞节点。
-
令 previousSibling 为 child 的前一个 同胞节点。
-
令 removedNodes 为空集合。
-
如果 child 的父节点非 null:
-
将 removedNodes 设置为 « child »。
-
移除 child,并将suppressObservers 设置 为 true。
只有当 child 是 node 时,上述条件才可能为 false。
-
-
如果 node 是一个
DocumentFragment节点,则令 nodes 为 node 的子节点;否则为 « node »。 -
将 node 插入 parent 中,在 referenceChild 之前, 并将suppressObservers 设置为 true。
-
为 parent 将树突变记录入队,并使用 nodes、 removedNodes、previousSibling 和 referenceChild。
-
返回 child。
要在一个节点 parent 内,用一个节点或 null node 全部替换:
-
令 removedNodes 为 parent 的子节点。
-
令 addedNodes 为空集合。
-
如果 node 是一个
DocumentFragment节点,则将 addedNodes 设置为 node 的子节点。 -
否则,如果 node 非 null,则将 addedNodes 设置为 « node »。
-
按树顺序移除 parent 的所有子节点, 并将suppressObservers 设置为 true。
-
如果 node 非 null,则将 node 插入 parent 中,在 null 之前,并将suppressObservers 设置为 true。
-
如果 addedNodes 或 removedNodes 任一不 为空, 则为 parent 将树突变记录入队,并使用 addedNodes、 removedNodes、null 和 null。
此算法不会对 节点树 约束进行任何检查。规范作者需要谨慎使用它。
要从一个节点 parent 中预移除 一个节点 child:
-
如果 child 的父节点不是 parent,则抛出一个 "
NotFoundError"DOMException。 -
移除 child。
-
返回 child。
要移除一个节点 node,并带有 一个 可选布尔值 suppressObservers(默认为 false):
-
令 parent 为 node 的父节点。
-
断言:parent 非 null。
-
给定 node,运行实时范围预移除步骤。
-
对于每个
NodeIterator对象 iterator,如果其 根的节点文档是 node 的 节点 文档:给定 node 和 iterator,运行NodeIterator预移除步骤。 -
令 oldPreviousSibling 为 node 的前一个 同胞节点。
-
令 oldNextSibling 为 node 的下一个同胞节点。
-
如果 parent 的根是一个影子根,并且 parent 是一个插槽,其已分配节点是 空列表, 则为 parent 运行发出插槽变更信号。
-
使用 node、true 和 parent 运行移除步骤。
-
令 isParentConnected 为 parent 的连接状态。
-
如果 node 是自定义的,且 isParentConnected 为 true, 则 使用 node、回调名称 "
disconnectedCallback" 和 « » 将自定义元素回调 反应入队。 -
对于 node 的每个影子包含后代 descendant,按 影子包含树顺序:
-
使用 descendant、 false 和 parent 运行移除步骤。
-
如果 descendant 是自定义的,且 isParentConnected 为 true,则使用 descendant、 回调名称 "
disconnectedCallback" 和 « » 将自定义元素 回调反应入队。
-
-
添加临时注册观察器 ,参数为 node 和 parent。
-
如果 suppressObservers 为 false,则为 parent 将树 突变记录入队,并使用 « »、« node »、oldPreviousSibling 和 oldNextSibling。
-
为 parent 运行子节点变更步骤。
4.2.4.
混入 NonElementParentNode
Web 兼容性阻止 getElementById()
方法暴露在元素上(因此也不能暴露在 ParentNode 上)。
interface mixin {NonElementParentNode Element ?getElementById (DOMString ); };elementId Document includes NonElementParentNode ;DocumentFragment includes NonElementParentNode ;
要在给定一个节点 node 和一个 字符串 elementId 的情况下按 ID 获取元素,返回 node 的后代中,按树序排列的 第一个其 ID 为 elementId 的元素; 否则,如果没有这样的元素,则返回 null。
4.2.5.
混入 DocumentOrShadowRoot
interface mixin {DocumentOrShadowRoot readonly attribute CustomElementRegistry ?customElementRegistry ; };Document includes DocumentOrShadowRoot ;ShadowRoot includes DocumentOrShadowRoot ;
registry = documentOrShadowRoot .customElementRegistry-
返回 documentOrShadowRoot 的
CustomElementRegistry对象(如果有); 否则返回 null。
customElementRegistry getter
步骤
为:
DocumentOrShadowRoot
mixin 也预期会被其他
想要定义在文档和
影子根之间共享的 API
的标准使用。
4.2.6. 混入 ParentNode
interface mixin { [ParentNode SameObject ]readonly attribute HTMLCollection children ;readonly attribute Element ?firstElementChild ;readonly attribute Element ?lastElementChild ;readonly attribute unsigned long childElementCount ; [CEReactions ,Unscopable ]undefined prepend ((Node or DOMString )...); [nodes CEReactions ,Unscopable ]undefined append ((Node or DOMString )...); [nodes CEReactions ,Unscopable ]undefined replaceChildren ((Node or DOMString )...); [nodes CEReactions ]undefined moveBefore (Node ,node Node ?);child Element ?querySelector (DOMString ); [selectors NewObject ]NodeList querySelectorAll (DOMString ); };selectors Document includes ParentNode ;DocumentFragment includes ParentNode ;Element includes ParentNode ;
collection = node .children- 返回子元素。
element = node .firstElementChild- 返回第一个属于元素的子节点;否则返回 null。
element = node .lastElementChild- 返回最后一个属于元素的子节点;否则返回 null。
node . prepend(nodes)-
将 nodes 插入到 node 的第一个子节点之前,同时 将 nodes 中的字符串替换为等效的
Text节点。如果违反了 节点树 的约束,则抛出一个 "
HierarchyRequestError"DOMException。 node . append(nodes)-
将 nodes 插入到 node 的最后一个子节点之后,同时将 nodes 中的字符串替换为等效的
Text节点。如果违反了 节点树 的约束,则抛出一个 "
HierarchyRequestError"DOMException。 node . replaceChildren(nodes)-
用 nodes 替换 node 的所有子节点, 同时将 nodes 中的字符串替换为等效的
Text节点。如果违反了 节点树 的约束,则抛出一个 "
HierarchyRequestError"DOMException。 node . moveBefore(movedNode, child)-
如果 child 非 null,则在不先移除的情况下,将 movedNode 移动到 node 中 child 之后;否则移动到 node 的最后一个子节点之后。此 方法会保留与 movedNode 关联的状态。
如果违反了 节点树 的约束,或者无法保留与被移动节点关联的状态,则抛出一个 "
HierarchyRequestError"DOMException。 node . querySelector(selectors)node . querySelectorAll(selectors)
children getter 步骤是返回一个
以 this
为根、仅匹配元素
子节点的
HTMLCollection
集合。
prepend(nodes) 方法步骤是:
append(nodes) 方法步骤是:
-
令 node 为给定 nodes 和 this 的节点文档将节点转换为一个节点的结果。
replaceChildren(nodes) 方法
步骤
是:
moveBefore(node, child)
方法步骤是:
querySelector(selectors) 方法
步骤是:针对this
使用 selectors 运行作用域匹配选择器
字符串,如果结果不是空列表,则返回其第一个结果;否则返回 null。
querySelectorAll(selectors)
方法
步骤是返回针对this
使用 selectors 运行
作用域匹配选择器字符串所得的静态结果。
4.2.7. 混入 NonDocumentTypeChildNode
Web 兼容性阻止 previousElementSibling
和
nextElementSibling
属性暴露在 doctype 上(因此也不能暴露在
ChildNode 上)。
interface mixin {NonDocumentTypeChildNode readonly attribute Element ?previousElementSibling ;readonly attribute Element ?nextElementSibling ; };Element includes NonDocumentTypeChildNode ;CharacterData includes NonDocumentTypeChildNode ;
element = node .previousElementSibling- 返回第一个先于它的、且为元素的兄弟节点; 否则返回 null。
element = node .nextElementSibling- 返回第一个跟随于它的、且为元素的兄弟节点; 否则返回 null。
4.2.8.
混入 ChildNode
interface mixin { [ChildNode CEReactions ,Unscopable ]undefined before ((Node or DOMString )...); [nodes CEReactions ,Unscopable ]undefined after ((Node or DOMString )...); [nodes CEReactions ,Unscopable ]undefined replaceWith ((Node or DOMString )...); [nodes CEReactions ,Unscopable ]undefined remove (); };DocumentType includes ChildNode ;Element includes ChildNode ;CharacterData includes ChildNode ;
node .before(...nodes)-
将 nodes 插入到 node 之前,同时将 nodes 中的字符串替换为等效的
Text节点。如果违反了 节点树 的约束,则抛出一个 "
HierarchyRequestError"DOMException。 node .after(...nodes)-
将 nodes 插入到 node 之后,同时将 nodes 中的字符串替换为等效的
Text节点。如果违反了 节点树 的约束,则抛出一个 "
HierarchyRequestError"DOMException。 node .replaceWith(...nodes)-
用 nodes 替换 node,同时将 nodes 中的字符串 替换为等效的
Text节点。如果违反了 节点树 的约束,则抛出一个 "
HierarchyRequestError"DOMException。 node .remove()- 移除 node。
before(nodes) 方法步骤是:
after(nodes) 方法步骤是:
replaceWith(nodes) 方法步骤是:
4.2.9. 混入 Slottable
interface mixin {Slottable readonly attribute HTMLSlotElement ?assignedSlot ; };Element includes Slottable ;Text includes Slottable ;
4.2.10.
旧式集合:NodeList
和 HTMLCollection
集合(collection) 是一个表示 节点列表的对象。 集合可以是 实时(live) 或 静态(static)。 除非另有说明,集合必须是实时的。
如果集合是实时的, 那么该对象上的属性和方法必须针对实际底层数据操作,而不是数据快照。
当集合创建时,会与其关联一个筛选器和一个根节点。
随后,集合便 表示 一个以集合的根节点为根的子树视图,其中仅包含与 给定过滤器匹配的节点。该视图是线性的。除非有相反的具体要求,否则 位于集合中的节点必须按照树顺序排序。
4.2.10.1.
接口 NodeList
[Exposed =Window ]interface {NodeList getter Node ?item (unsigned long );index readonly attribute unsigned long length ;iterable <Node >; };
- collection .
length - 返回集合中的节点 数量。
- element = collection .
item(index)- element = collection[index]
- 返回集合中索引为 index 的节点。这些 节点按树顺序排序。
该对象的受支持的属性索引是从零到 由集合表示的节点数量减一这一范围内的数字。如果不存在这样的 元素,则不存在受支持的属性索引。
length 属性必须返回
由集合表示的节点数量。
item(index) 方法必须返回集合中的第
index 个节点。如果集合中不存在第
index 个节点,则该方法必须
返回 null。
4.2.10.2.
接口HTMLCollection
[Exposed =Window ,LegacyUnenumerableNamedProperties ]interface {HTMLCollection readonly attribute unsigned long length ;getter Element ?item (unsigned long );index getter Element ?(namedItem DOMString ); };name
一个 HTMLCollection
对象是一个由元素组成的集合。
HTMLCollection
是一个我们无法从 Web 中摆脱的历史遗留产物。
虽然开发者当然可以继续使用它,但新的 API 标准设计者不应使用
它(应改用 IDL 中的 sequence<T>)。
- collection .
length - 返回 集合中元素的数量。
- element = collection .
item(index)- element = collection[index]
- 返回集合中索引为 index 的元素。 这些元素按树 序排序。
- element = collection .
namedItem(name)- element = collection[name]
- 返回 collection 中第一个 ID 或 name 为 name 的元素。
对象的支持的属性索引是范围从 零到由集合表示的元素数量减一的数字。如果没有这样的 元素,则不存在支持的属性索引。
length getter 步骤是返回
由集合表示的节点数量。
item(index) 方法步骤是
返回集合中的第
indexth 个元素。如果集合中
没有第 indexth 个元素,则该方法
必须返回 null。
支持的属性名称是这些步骤返回的列表中的值:
-
令 result 为空列表。
-
返回 result。
namedItem(key) 方法步骤为:
-
如果 key 是空字符串,则返回 null。
-
如果没有这样的元素,则返回 null。
4.3. 突变 观察者
每个相同来源窗口代理都有一个突变观察者微任务排队(布尔值),其初始值为false。[HTML]
每个相似源窗口代理还具有
待处理的变更
观察器(一个由零个或多个
MutationObserver
对象组成的集合),其初始值为空。
每个同源类似窗口代理还有一个变更观察器 计数器 (一个数字),其初始值为 0。
要 排队一个突变观察者微任务:
-
如果外围代理的突变观察者微任务已排队为 true,则返回。
-
将外围代理的突变观察者微任务已排队设为 true。
要通知 变更观察器:
-
将周边代理的变更观察器微任务 已入队标志设置为 false。
-
令 notifyList 为对以下对象进行排序的结果: 周边代理的待处理的变更 观察器,按升序排列,其中 a 小于 b 的条件是 a 的创建索引小于 b 的创建索引。
-
对于 notifyList 中的每个 mo:
-
移除临时注册 观察器,针对 mo。
-
如果 records 非空,则调用 mo 的回调,传入 « records, mo » 和 "
report",并将回调的 this 值设为 mo。
-
对于 signalSet 中的每个 slot:触发一个 事件,其名称为
slotchange,将其bubbles属性设置为 true, 目标为 slot。
每个节点都有一个已注册观察器 列表(一个列表,包含 零个或多个已注册 观察器),初始为空。
一个已注册
观察器由一个
观察器(一个MutationObserver
对象)和
选项(一个MutationObserverInit
字典)组成。
一个临时 注册观察器是一个 已注册 观察器,它还包含一个 来源(一个已注册观察器,但不是 临时注册观察器)。
临时注册观察器用于跟踪
给定节点的后代中的变更,即使节点已被移除或
移动,从而
确保在该节点的
原父节点上将
subtree
设置为 true 时,不会遗漏这些变更。
它们将在下次通知变更观察器时被移除。
要添加 临时注册观察器,给定一个节点 node 和一个 节点 parent:
-
对于 parent 的每个包含自身的祖先 inclusiveAncestor, 然后对于 inclusiveAncestor 的 已注册观察器列表中的每个 registered:
要为一个MutationObserver
对象
observer 移除临时注册观察器:
4.3.1.
接口 MutationObserver
[Exposed =Window ]interface {MutationObserver constructor (MutationCallback );callback undefined observe (Node ,target optional MutationObserverInit = {});options undefined disconnect ();sequence <MutationRecord >takeRecords (); };callback =MutationCallback undefined (sequence <MutationRecord >,mutations MutationObserver );observer dictionary {MutationObserverInit boolean =childList false ;boolean ;attributes boolean ;characterData boolean =subtree false ;boolean ;attributeOldValue boolean ;characterDataOldValue sequence <DOMString >; };attributeFilter
一个 MutationObserver
对象可用于观察节点
树的变更。
每个 MutationObserver
对象都具有以下关联概念:
- 一个在创建时设置的回调。
- 一个在创建时设置的创建索引(一个数字)。
- 一个节点列表(一个由 节点的弱引用组成的列表),其初始值 为空。
- 一个临时节点集合(一个由 节点的弱引用 组成的集合),其初始值 为空。
- 一个记录队列(一个包含
零个或多个
MutationRecord对象的队列), 其初始值为空。
observer = newMutationObserver(callback)- 构造一个
MutationObserver对象,并将其回调设为 callback。调用 callback 时,会将一个由MutationRecord对象组成的列表 作为第一个参数,并将构造的MutationObserver对象作为第二个参数。它会在 使用observe()方法注册的节点发生 变更后被调用。 observer .observe(target, options)-
指示用户代理观察给定的 target
(一个节点),并根据
options(一个对象)指定的条件
报告任何变更。
options 参数允许通过对象成员设置变更 观察选项。可以使用的对象成员 如下:
childList- 如果需要观察 target 的子节点的 变更,则设为 true。
attributes- 如果需要观察 target 的
属性
的变更,则设为 true。如果指定了
attributeOldValue或attributeFilter, 则可以 省略。 characterData- 如果需要观察 target 的
数据的
变更,则设为 true。如果指定了
characterDataOldValue, 则可以省略。 subtree- 如果不仅需要观察 target 的变更, 还需要观察 target 的 后代的 变更,则设为 true。
attributeOldValue- 如果
attributes为 true 或被省略, 并且需要记录 target 的 属性在变更前的 值, 则设为 true。 characterDataOldValue- 如果
characterData被设为 true 或被省略,并且需要记录 target 在 变更前的数据, 则设为 true。 attributeFilter- 如果不需要观察所有
属性
变更,且
attributes为 true 或被省略,则设为一个 属性 局部名称(不含命名空间) 的列表。
observer .disconnect()- 使 observer 停止观察任何变更。在再次使用
observe()方法之前, observer 的回调不会被调用。 observer .takeRecords()- 清空记录 队列,并 返回其中原有的内容。
new MutationObserver(callback)
构造函数的步骤如下:
observe(target, options)
方法的步骤如下:
-
如果 options["
attributeOldValue"] 或 options["attributeFilter"] 存在,并且 options["attributes"] 不存在,则将 options["attributes"] 设为 true。 -
如果 options["
characterDataOldValue"] 存在,且 options["characterData"] 不 存在,则将 options["characterData"] 设为 true。 -
如果 options["
childList"]、 options["attributes"] 和 options["characterData"] 均不为 true,则抛出一个TypeError。 -
如果 options["
attributeOldValue"] 为 true,且 options["attributes"] 为 false,则抛出一个TypeError。 -
如果 options["
attributeFilter"] 存在,且 options["attributes"] 为 false,则抛出一个TypeError。 -
如果 options["
characterDataOldValue"] 为 true,且 options["characterData"] 为 false,则抛出一个TypeError。 -
令 registered 为 target 的已注册观察器列表中的已注册观察器,该观察器不是临时已注册观察器,且其 观察器为this(如果存在);否则 为 null。
如果 target 曾位于this 所观察的子树中,且已被 移除或 移动,则 target 的已注册观察器列表也可能包含 临时已注册观察器,其观察器为 this。这些观察器会被忽略,因为它们将在下次通知变更 观察器时被移除。
-
如果 registered 不为 null:
-
否则:
disconnect() 方法的步骤如下:
4.3.2. 排队突变记录
要为 target 将一个 变更记录加入队列,其类型为 type,并具有 name、namespace、oldValue、addedNodes、 removedNodes、previousSibling 和 nextSibling:
-
令 interestedObservers 为一个空有序映射。
-
令 nodes 为 target 的包含自身的祖先。
-
对于 nodes 中的每个 node,然后对于 node 的已注册观察器 列表中的每个 registered:
-
令 options 为 registered 的 选项。
-
如果以下条件均不成立
- node 不是 target,且
options["
subtree"] 为 false - type 为 "
attributes",且 options["attributes"] 不存在 或为 false - type 为 "
attributes", options["attributeFilter"] 存在,且 options["attributeFilter"] 不包含 name,或 namespace 非 null - type 为 "
characterData",且 options["characterData"] 不存在或为 false - type 为 "
childList",且 options["childList"] 为 false
则:
-
令 mo 为 registered 的观察器。
-
如果 interestedObservers[mo] 不存在,则 将 interestedObservers[mo] 设置 为 null。
-
如果 type 为 "
attributes",且 options["attributeOldValue"] 为 true,或者 type 为 "characterData",且 options["characterDataOldValue"] 为 true,则 将 interestedObservers[mo] 设置 为 oldValue。
- node 不是 target,且
options["
-
-
如果 interestedObservers 为空, 则返回。
-
对于 interestedObservers 中的每个 observer → mappedOldValue 映射条目:
-
令 record 为一个新的
MutationRecord对象,其type设置为 type,target设置为 target,attributeName设置为 name,attributeNamespace设置为 namespace,oldValue设置为 mappedOldValue,addedNodes设置为 addedNodes,removedNodes设置为 removedNodes,previousSibling设置为 previousSibling,并将nextSibling设置为 nextSibling。
-
要为 target,带 addedNodes、removedNodes、previousSibling 和 nextSibling 排队一个树突变记录:
4.3.3.
接口 MutationRecord
[Exposed =Window ]interface {MutationRecord readonly attribute DOMString type ; [SameObject ]readonly attribute Node target ; [SameObject ]readonly attribute NodeList addedNodes ; [SameObject ]readonly attribute NodeList removedNodes ;readonly attribute Node ?previousSibling ;readonly attribute Node ?nextSibling ;readonly attribute DOMString ?attributeName ;readonly attribute DOMString ?attributeNamespace ;readonly attribute DOMString ?oldValue ; };
record .type- 如果发生"
attributes"类型的 属性 变更,则返回该值。 如果发生"characterData"类型的变更,即CharacterData节点的变更,则返回该值。而 如果发生"childList"类型的变更,即 树中的 节点发生变更,也返回该值。 record .target- 返回节点,即
受到变更
影响的节点,具体取决于
type。 对于 "attributes",它是 元素,其 属性发生了变更。 对于 "characterData",它是一个CharacterData节点。对于 "childList", 它是节点,其 子节点 发生了变更。 record .addedNodesrecord .removedNodes- 分别返回添加的节点和 移除的节点。
record .previousSiblingrecord .nextSibling- 返回前一个同胞节点和后一个同胞节点, 分别对应 被添加或移除的节点;否则返回 null。
record .attributeName- 返回本地名称,对应发生变更的属性;否则返回 null。
record .attributeNamespace- 返回命名空间,对应发生变更的属性;否则返回 null。
record .oldValue- 返回值取决于
type。 对于 "attributes",它是 值, 即发生 变更的属性 在变更前的值。 对于 "characterData",它是 数据,属于发生变更的 节点在变更前的数据。 对于 "childList",它是 null。
type、target、
addedNodes、
removedNodes、
previousSibling、
nextSibling、
attributeName、
attributeNamespace 和
oldValue 属性必须返回它们被初始化为的值。
4.4. 接口 Node
[Exposed =Window ]interface :Node EventTarget {const unsigned short ELEMENT_NODE = 1;const unsigned short ATTRIBUTE_NODE = 2;const unsigned short TEXT_NODE = 3;const unsigned short CDATA_SECTION_NODE = 4;const unsigned short = 5; // legacyENTITY_REFERENCE_NODE const unsigned short = 6; // legacyENTITY_NODE const unsigned short PROCESSING_INSTRUCTION_NODE = 7;const unsigned short COMMENT_NODE = 8;const unsigned short DOCUMENT_NODE = 9;const unsigned short DOCUMENT_TYPE_NODE = 10;const unsigned short DOCUMENT_FRAGMENT_NODE = 11;const unsigned short = 12; // legacyNOTATION_NODE readonly attribute unsigned short nodeType ;readonly attribute DOMString nodeName ;readonly attribute USVString baseURI ;readonly attribute boolean isConnected ;readonly attribute Document ?ownerDocument ;Node getRootNode (optional GetRootNodeOptions = {});options readonly attribute Node ?parentNode ;readonly attribute Element ?parentElement ;boolean hasChildNodes (); [SameObject ]readonly attribute NodeList childNodes ;readonly attribute Node ?firstChild ;readonly attribute Node ?lastChild ;readonly attribute Node ?previousSibling ;readonly attribute Node ?nextSibling ; [CEReactions ]attribute DOMString ?nodeValue ; [CEReactions ]attribute DOMString ?textContent ; [CEReactions ]undefined normalize (); [CEReactions ,NewObject ]Node cloneNode (optional boolean =subtree false );boolean isEqualNode (Node ?);otherNode boolean isSameNode (Node ?); // legacy alias of ===otherNode const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;unsigned short compareDocumentPosition (Node );other boolean contains (Node ?);other DOMString ?lookupPrefix (DOMString ?);namespace DOMString ?lookupNamespaceURI (DOMString ?);prefix boolean isDefaultNamespace (DOMString ?); [namespace CEReactions ]Node insertBefore (Node ,node Node ?); [child CEReactions ]Node appendChild (Node ); [node CEReactions ]Node replaceChild (Node ,node Node ); [child CEReactions ]Node removeChild (Node ); };child dictionary {GetRootNodeOptions boolean =composed false ; };
Node 是一个抽象
接口,供所有节点使用。你无法
直接获取其实例。
每个节点都有一个关联的 节点 文档,在创建时设置,它是一个 文档。
一个节点的获取父节点算法, 给定一个 event,返回该 节点的已分配插槽,如果该节点已被分配;否则返回 该节点的父节点。
要创建一个节点,使其 实现接口 interface,给定一个 文档 document:
node .nodeType-
返回与 node 的类型对应的数字,如下所示:
Element(1).Node.ELEMENT_NODEAttr(2).Node.ATTRIBUTE_NODE- 一个专属
Text节点 (3).Node.TEXT_NODECDATASection(4).Node.CDATA_SECTION_NODEProcessingInstruction(7).Node.PROCESSING_INSTRUCTION_NODEComment(8).Node.COMMENT_NODEDocument(9).Node.DOCUMENT_NODEDocumentType(10).Node.DOCUMENT_TYPE_NODEDocumentFragment(11).Node.DOCUMENT_FRAGMENT_NODE
node .nodeName-
返回与 node 的类型对应的字符串,如下所示:
Element- 其HTML 大写限定名称。
Attr- 其限定名称。
- 一个专属
Text节点 - "
#text"。 CDATASection- "
#cdata-section"。 ProcessingInstruction- 其目标。
Comment- "
#comment"。 Document- "
#document"。 DocumentType- 其名称。
DocumentFragment- "
#document-fragment"。
nodeType 获取器的步骤是根据this 实现的接口进行分支,并返回第一个匹配的
条目:
ElementELEMENT_NODE(1)AttrATTRIBUTE_NODE(2);- 一个专属
Text节点 TEXT_NODE(3);CDATASectionCDATA_SECTION_NODE(4);ProcessingInstructionPROCESSING_INSTRUCTION_NODE(7);CommentCOMMENT_NODE(8);DocumentDOCUMENT_NODE(9);DocumentTypeDOCUMENT_TYPE_NODE(10);DocumentFragmentDOCUMENT_FRAGMENT_NODE(11).
nodeName 获取器的步骤是根据
this 实现的接口进行分支,返回第一个匹配的条目:
Element- 其HTML 大写限定名称。
Attr- 其限定名称。
- 一个专属
Text节点 - "
#text"。 CDATASection- "
#cdata-section"。 ProcessingInstruction- 其目标。
Comment- "
#comment"。 Document- "
#document"。 DocumentType- 其名称。
DocumentFragment- "
#document-fragment"。
node .baseURI- 返回 node 的节点文档的基础 URL。
baseURI 获取器的步骤如下:
-
返回经过序列化的 baseURL。
node .isConnected-
如果 node 已连接,则返回 true;否则返回 false。
node .ownerDocument- 返回节点文档。 对于文档,返回 null。
node .getRootNode()- 返回 node 的根。
node . getRootNode({ composed:true })- 返回 node 的包含影子树的根。
node .parentNode- 返回父节点。
node .parentElement- 返回父 元素。
node .hasChildNodes()- 返回 node 是否具有 子节点。
node .childNodes- 返回子节点。
node .firstChild- 返回第一个子节点。
node .lastChild- 返回最后一个子节点。
node .previousSibling- 返回 上一个兄弟节点。
node .nextSibling- 返回 下一个 兄弟节点。
isConnected 获取器的步骤是:如果
this 已连接,则返回 true;否则返回 false。
ownerDocument 获取器的步骤是:如果
this 是一个文档,则返回 null;否则返回 this 的节点
文档。
一个文档的节点文档就是该 文档本身。所有节点在任何时候都具有一个节点 文档。
getRootNode(options) 方法的步骤是:
如果 options["composed"]
为 true,则返回 this
的包含影子树的根;否则返回
this 的
根。
parentNode 获取器的步骤是返回
this 的父节点。
parentElement 获取器的步骤是返回
this 的父元素。
hasChildNodes() 方法的步骤是:如果
this 具有子节点,
则返回 true;否则返回 false。
childNodes 获取器的步骤是返回一个
以 this 为根、仅匹配
子节点的
NodeList。
firstChild 获取器的步骤是返回
this 的第一个
子节点。
lastChild 获取器的步骤是返回 this 的
最后一个
子节点。
previousSibling 获取器的步骤是返回
this 的上一个兄弟节点。
nextSibling 获取器的步骤是返回
this 的下一个
兄弟节点。
nodeValue 获取器的步骤是根据
this 实现的接口,返回以下对应的值:
Attr- this 的值。
CharacterData- this 的数据。
- 其他情况
- Null。
nodeValue
设置器的步骤是:如果给定值为 null,则将其视为空字符串,
然后根据 this
实现的接口,执行下述操作:
要使用节点 node 获取文本内容, 请根据 node 实现的接口返回以下对应的值:
DocumentFragmentElement- node 的后代文本内容。
Attr- node 的值。
CharacterData- node 的数据。
- 其他情况
- Null。
textContent 获取器的步骤是
返回使用 this 运行获取文本内容的结果。
要在节点 parent 内 使用字符串 string 以字符串替换所有内容, 请运行以下步骤:
-
令 node 为 null。
-
如果 string 不是空字符串,则将 node 设置为 使用 parent 的节点文档和 string 作为参数创建文本 节点的结果。
-
在 parent 内,使用 node 替换所有内容。
要使用节点 node 和 字符串 value 设置文本内容, 请根据 node 实现的接口执行下述操作:
DocumentFragmentElement-
在 node 内使用 value 以字符串替换 所有内容。
Attr-
使用 node 和 value 设置现有属性的值。
CharacterData- 其他情况
-
不执行任何操作。
textContent
设置器的步骤是:如果给定值为 null,则将其视为空字符串,
然后使用 this
和给定值运行设置文本内容。
node .normalize()- 移除空的专属
Text节点,并将剩余连续专属Text节点的 数据连接到这些节点中的第一个节点。
normalize() 方法的步骤是:对于
this 的每个后代专属
Text 节点
node,
运行以下步骤:
-
令 length 为 node 的长度。
-
如果 length 为零,则移除 node,并继续处理 下一个专属
Text节点(如果存在)。 -
令 data 为 node 的连续专属
Text节点(不包括自身)的 数据按 树顺序进行连接的结果。 -
使用 length、0 和 data 替换 数据,替换对象为 node。
-
令 currentNode 为 node 的下一个兄弟节点。
-
当 currentNode 是一个专属
Text节点时:-
对于起始 节点为 currentNode 的每个活跃范围: 将 length 加到其起始偏移量,并将其 起始节点设置为 node。
-
对于活跃范围中结束节点为 currentNode 的每个范围:将 length 加到其结束偏移量,并将其结束节点设置为 node。
-
对于活跃范围中起始 节点为 currentNode 的 父节点,且起始 偏移量为 currentNode 的 索引的每个范围:将其起始 节点设置为 node,并将其 起始偏移量设置为 length。
-
对于活跃范围中结束节点为 currentNode 的 父节点,且结束 偏移量为 currentNode 的 索引的每个范围:将其结束节点设置为 node,并将其 结束偏移量设置为 length。
-
将 currentNode 的长度加到 length。
-
将 currentNode 设置为其下一个 兄弟节点。
-
-
移除 node 的连续专属
Text节点 (不包括自身),按树顺序进行。
node . cloneNode([subtree = false])- 返回 node 的副本。如果 subtree 为 true,该副本还包含 node 的后代。
node . isEqualNode(otherNode)- 返回 node 和 otherNode 是否具有相同的属性。
HTML 为多个元素定义了克隆步骤,例如
input、
script,
以及
template。
SVG 也应当为其
script
元素执行相同的操作,但目前没有这样做。
要在给定一个节点
node
和一个可选的文档 document
(默认为 node 的节点文档)、布尔值
subtree(默认为 false)、节点或 null 值
parent(默认为 null),以及 null 或
CustomElementRegistry
对象 fallbackRegistry
(默认为 null)时,克隆节点:
-
令 copy 为使用 node、 document 和 fallbackRegistry 克隆单个节点的结果。
-
如果 parent 不为 null,则将 copy 追加到 parent。
-
如果 subtree 为 true,则对于 node 的子节点中的每个 child,按树顺序:使用 child 克隆 节点,其中 document 设置为 document, subtree 设置为 subtree, parent 设置为 copy,并且 fallbackRegistry 设置为 fallbackRegistry。
-
如果 node 是一个元素,node 是一个 影子 宿主,并且 node 的影子根的 可克隆为 true:
-
如果 shadowRootRegistry 是全局自定义元素 注册表,则将 shadowRootRegistry 设置为 document 的 自定义元素注册表的有效全局自定义 元素注册表。
-
使用 copy、node 的 影子根的模式、node 的 影子根的委托 焦点、node 的 影子根的可序列化、node 的 影子根的槽位 分配、true 和 shadowRootRegistry 附加影子根。
-
将 copy 的影子根的 保持自定义元素 注册表为 null设置为 node 的 影子根的保持自定义元素 注册表为 null。
-
对于 node 的影子根的 子节点中的每个 child,按树顺序:使用 child 克隆节点,其中 document 设置为 document, subtree 设置为 true,并且 parent 设置为 copy 的影子根。
这里有意不传递 fallbackRegistry 参数。
-
返回 copy。
要在给定一个节点 node、
文档
document,以及 null 或一个 CustomElementRegistry
对象
fallbackRegistry 时,克隆单个
节点:
-
令 copy 为 null。
-
如果 node 是一个元素:
-
令 registry 为 node 的自定义元素注册表。
-
如果 registry 为 null,则将 registry 设置为 fallbackRegistry。
-
如果 registry 是全局自定义元素 注册表,则将 registry 设置为 document 的自定义元素注册表的 有效全局自定义 元素注册表。
-
将 copy 设置为创建 元素的结果,给定 document、node 的局部 名称、node 的 命名空间、node 的命名空间前缀、 node 的
is值、false 和 registry。
-
-
否则,如果 node 是一个文档,则将 copy 设置为 创建 文档的结果,该文档实现与 node 相同的接口,并使用 document 的相关领域。
-
根据 node 实现的接口,满足以下附加要求:
DocumentDocumentTypeAttrTextComment-
将 copy 的数据设置为与 node 相同的值。
ProcessingInstruction- 其他情况
-
不执行任何操作。
-
如果 node 是一个文档,则将 document 设置为 copy。
-
将 copy 的节点文档设置为 document。
-
返回 copy。
cloneNode(subtree) 方法的步骤如下:
-
如果 this 是一个影子根,则抛出一个 "
NotSupportedError"DOMException。
isSameNode(otherNode) 方法的步骤是:
如果 otherNode 是 this,则返回 true;否则返回 false。
node .compareDocumentPosition(other)-
返回一个位掩码,指示 other 相对于
node 的位置。以下是可以设置的位:
(1)Node.DOCUMENT_POSITION_DISCONNECTED- 当 node 和 other 不在 同一棵树中时设置。
(2)Node.DOCUMENT_POSITION_PRECEDING- 当 other 位于 node 之前时设置。
(4)Node.DOCUMENT_POSITION_FOLLOWING- 当 other 位于 node 之后时设置。
(8)Node.DOCUMENT_POSITION_CONTAINS- 当 other 是 node 的祖先时设置。
(16,十六进制为 10)Node.DOCUMENT_POSITION_CONTAINED_BY- 当 other 是 node 的后代时设置。
node .contains(other)- 如果 other 是 node 的含自身的后代,则返回 true; 否则返回 false。
以下是 compareDocumentPosition()
作为掩码返回的常量:
DOCUMENT_POSITION_DISCONNECTED(1);DOCUMENT_POSITION_PRECEDING(2);DOCUMENT_POSITION_FOLLOWING(4);DOCUMENT_POSITION_CONTAINS(8);DOCUMENT_POSITION_CONTAINED_BY(16, 十六进制为 10);DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC(32,十六进制为 20)。
compareDocumentPosition(other)
方法的
步骤如下:
-
如果 this 是 other,则返回零。
-
令 node1 为 other,令 node2 为 this。
-
令 attr1 和 attr2 为 null。
-
如果 node2 是一个属性:
-
将 attr2 设置为 node2,并将 node2 设置为 attr2 的 元素。
-
如果 attr1 和 node1 均不为 null,且 node2 是 node1:
-
-
如果 attr 等于 attr1,则 返回将
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC和DOCUMENT_POSITION_PRECEDING相加的结果。 -
如果 attr 等于 attr2,则 返回将
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC和DOCUMENT_POSITION_FOLLOWING相加的结果。
-
-
-
-
如果 node1 或 node2 为 null,或者 node1 的根不等于 node2 的根,则返回将
DOCUMENT_POSITION_DISCONNECTED、DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, 以及DOCUMENT_POSITION_PRECEDING或DOCUMENT_POSITION_FOLLOWING中的任意一个 相加的结果,前提是这一选择必须保持一致。决定返回
DOCUMENT_POSITION_PRECEDING还是DOCUMENT_POSITION_FOLLOWING通常通过指针比较来实现。在 JavaScript 实现中,可以使用缓存的Math值。. random() -
如果 node1 是 node2 的祖先且 attr1 为 null,或者 node1 是 node2 且 attr2 不为 null,则返回将
DOCUMENT_POSITION_CONTAINS与DOCUMENT_POSITION_PRECEDING相加的结果。 -
如果 node1 是 node2 的后代且 attr2 为 null,或者 node1 是 node2 且 attr1 不为 null,则返回将
DOCUMENT_POSITION_CONTAINED_BY与DOCUMENT_POSITION_FOLLOWING相加的结果。 -
如果 node1 位于 node2 之前,则返回
DOCUMENT_POSITION_PRECEDING。
contains(other) 方法的步骤是:
如果 other 是 this 的含自身的后代,则返回 true;否则返回 false
(包括 other 为 null 的情况)。
要 查找 命名空间前缀, 对于使用 namespace 的 element,运行以下步骤:
要使用 prefix 为 node 查找命名空间, 请根据 node 实现的接口进行区分:
ElementDocumentDocumentTypeDocumentFragment-
返回 null。
Attr- 其他情况
lookupPrefix(namespace) 方法的步骤如下:
-
如果 namespace 为 null 或空字符串,则返回 null。
-
ElementDocumentDocumentTypeDocumentFragment-
返回 null。
Attr- 其他情况
lookupNamespaceURI(prefix) 方法的步骤
如下:
isDefaultNamespace(namespace) 方法的
步骤
如下:
-
如果 namespace 是空字符串,则将其设置为 null。
-
如果 defaultNamespace 与 namespace 相同,则返回 true;否则返回 false。
insertBefore(node, child)
方法的步骤是返回将 node 在 child 之前
预插入到 this
中的结果。
appendChild(node) 方法的步骤是
返回将 node 追加到 this 的结果。
replaceChild(node, child)
方法的步骤是返回在 this
内
使用 node 替换 child 的结果。
removeChild(child) 方法的步骤是
返回从 this 中
预移除
child 的结果。
对于节点 root,
具有限定名称
qualifiedName 的元素列表是由以下
算法返回的
HTMLCollection:
-
如果 qualifiedName 为 U+002A (*),则返回一个以 root 为根、其过滤器仅匹配后代元素的
HTMLCollection。 -
否则,如果 root 的节点文档是一个 HTML 文档, 则返回一个以 root 为根的
HTMLCollection, 其过滤器匹配以下后代元素: -
否则,返回一个以 root 为根的
HTMLCollection, 其过滤器匹配 后代元素中限定名称为 qualifiedName 的元素。
当使用相同的参数调用时,只要 root 的
节点
文档的类型没有改变,就可以返回
与先前调用所返回的相同的 HTMLCollection
对象。
对于节点 root,
具有命名空间
namespace 和局部名称 localName 的元素列表是由以下
算法返回的
HTMLCollection:
-
如果 namespace 是空字符串,则将其设置为 null。
-
如果 namespace 和 localName 都为 U+002A (*),则返回一个 以 root 为根的
HTMLCollection, 其过滤器匹配后代 元素。 -
如果 namespace 为 U+002A (*),则返回一个 以 root 为根的
HTMLCollection, 其过滤器匹配后代元素中 局部名称为 localName 的元素。 -
如果 localName 为 U+002A (*),则返回一个 以 root 为根的
HTMLCollection, 其过滤器匹配后代元素中 命名空间为 namespace 的元素。 -
返回一个 以 root 为根的
HTMLCollection, 其过滤器匹配 后代元素中命名空间为 namespace,且局部名称为 localName 的元素。
当使用相同的参数调用时,可以返回与
先前调用所返回的相同的 HTMLCollection
对象。
对于节点 root,
具有类名
classNames 的元素列表是由以下
算法返回的
HTMLCollection:
- 令 classes 为对 classNames 运行有序集合解析器的结果。
-
如果 classes 是空集合,则返回一个空的
HTMLCollection。 -
返回一个以 root 为根的
HTMLCollection, 其过滤器匹配 后代元素中具有 classes 中所有类的元素。如果 root 的节点 文档的模式 为 "
quirks",则对类的比较必须以 ASCII 大小写不敏感的方式进行;否则以 完全相同 的方式进行。
当使用相同的参数调用时,可以返回相同的 HTMLCollection
对象,即先前调用所
返回的对象。
4.5. 接口 Document
[Exposed =Window ]interface :Document Node {constructor (); [SameObject ]readonly attribute DOMImplementation implementation ;readonly attribute USVString URL ;readonly attribute USVString documentURI ;readonly attribute DOMString compatMode ;readonly attribute DOMString characterSet ;readonly attribute DOMString charset ; // legacy alias of .characterSetreadonly attribute DOMString inputEncoding ; // legacy alias of .characterSetreadonly attribute DOMString contentType ;readonly attribute DocumentType ?doctype ;readonly attribute Element ?documentElement ;HTMLCollection getElementsByTagName (DOMString );qualifiedName HTMLCollection getElementsByTagNameNS (DOMString ?,namespace DOMString );localName HTMLCollection getElementsByClassName (DOMString ); [classNames CEReactions ,NewObject ]Element createElement (DOMString ,localName optional (DOMString or ElementCreationOptions )= {}); [options CEReactions ,NewObject ]Element createElementNS (DOMString ?,namespace DOMString ,qualifiedName optional (DOMString or ElementCreationOptions )= {}); [options NewObject ]DocumentFragment createDocumentFragment (); [NewObject ]Text createTextNode (DOMString ); [data NewObject ]CDATASection createCDATASection (DOMString ); [data NewObject ]Comment createComment (DOMString ); [data NewObject ]ProcessingInstruction createProcessingInstruction (DOMString ,target DOMString ); [data CEReactions ,NewObject ]Node importNode (Node ,node optional (boolean or ImportNodeOptions )=options false ); [CEReactions ]Node adoptNode (Node ); [node NewObject ]Attr createAttribute (DOMString ); [localName NewObject ]Attr createAttributeNS (DOMString ?,namespace DOMString ); [qualifiedName NewObject ]Event createEvent (DOMString ); // legacy [interface NewObject ]Range createRange (); // NodeFilter.SHOW_ALL = 0xFFFFFFFF [NewObject ]NodeIterator createNodeIterator (Node ,root optional unsigned long = 0xFFFFFFFF,whatToShow optional NodeFilter ?=filter null ); [NewObject ]TreeWalker createTreeWalker (Node ,root optional unsigned long = 0xFFFFFFFF,whatToShow optional NodeFilter ?=filter null ); }; [Exposed =Window ]interface :XMLDocument Document {};dictionary {ElementCreationOptions CustomElementRegistry ?;customElementRegistry DOMString ; };is dictionary {ImportNodeOptions CustomElementRegistry ;customElementRegistry boolean =selfOnly false ; };
每个文档都有一个
关联的
编码(一种编码)、
内容类型(一个字符串)、
URL(一个URL)、
源(一个源)、
类型("xml" 或 "html")、
模式("no-quirks"、"quirks" 或
"limited-quirks")、
允许声明式影子根(一个布尔值),以及
自定义元素注册表(null 或一个 CustomElementRegistry
对象)。
[ENCODING]
[URL]
[HTML]
除非另有说明,一个文档的编码是
utf-8 编码,内容类型是
"application/xml",URL 是 "about:blank",
源是
一个不透明源,
类型是
"xml",模式是
"no-quirks",允许声明式影子根为 false,并且
自定义元素注册表为 null。
如果一个文档的
类型是
"xml",则称其为 XML
文档;
否则称其为 HTML 文档。
一个文档是
HTML 文档还是XML 文档,会影响
某些 API 的行为。
每个文档都有一个 关联的获取基础 URL 算法,该算法 返回一个URL 或 null。除非另有规定,否则返回 null。
每个文档都有一个基础 URL 覆盖值(一个 URL 或 null),初始值为 null。
在克隆一个文档时,会设置基础 URL 覆盖值。HTML
覆盖了获取基础
URL算法,以考虑
base 元素,以及使用 "about:" 方案的文档所
继承的基础 URL。[HTML]
当一个文档的
模式为
"no-quirks" 时,称其处于
无怪异
模式;
当其模式
为 "quirks" 时,称其处于怪异模式;
当其
有限怪异
模式对应的
模式为
"limited-quirks" 时,则称其处于有限怪异模式。
模式
只有在以下情况下才会从默认值改变:对于由文档,
其由HTML 解析器创建,并取决于 DOCTYPE
字符串是否存在及其值,
或由新的浏览上下文(初始 "about:blank")创建。[HTML]
无怪异模式最初称为“标准模式”, 而有限怪异模式 曾被称为“近乎标准模式”。这些名称已经更改,因为其细节现在 由标准定义。(也因为 Ian Hickson 认为这些原始名称 毫无意义,因此否决了它们。)
一个文档的获取父级算法,
在给定 event 时,如果 event 的 type
属性值为 "load",或者
文档没有
浏览上下文,则返回 null;否则返回该
文档的
相关全局对象。
要创建一个 文档,使其实现接口 interface, 给定一个领域 realm:
document = newDocument()- 返回一个新的文档。
document .implementation- 返回 document 的
DOMImplementation对象。 document .URLdocument .documentURI- 返回 document 的URL。
document .compatMode-
如果 document 的模式是 "
quirks", 则返回字符串 "BackCompat";否则返回 "CSS1Compat"。 document .characterSet- 返回 document 的 编码。
document .contentType- 返回 document 的 内容类型。
new Document()
构造器的
步骤是将 this 的源设置为
当前全局对象的关联的 Document 的源。[HTML]
与 createDocument()
不同,
此构造器不会
返回一个 XMLDocument
对象,而是返回一个文档
(Document
对象)。
implementation 获取器的步骤是返回与
this 关联的 DOMImplementation
对象。
URL 和
documentURI 获取器的步骤是返回 this 的
URL 的序列化结果。
compatMode 获取器的步骤是:
如果 this 的模式为
"quirks",则返回
"BackCompat";否则返回 "CSS1Compat"。
characterSet、
charset 和
inputEncoding 获取器的步骤是返回
this 的编码的名称。
contentType 获取器的步骤是返回
this 的内容类型。
- document .
doctype - 返回文档类型,如果 不存在, 则返回 null。
- document .
documentElement - 返回文档 元素。
collection = document . getElementsByTagName(qualifiedName)-
如果 qualifiedName 为 "
*",则返回一个包含所有 后代元素的HTMLCollection。否则,返回一个
HTMLCollection, 其中包含所有后代 元素中限定名称为 qualifiedName 的元素。 (对于 HTML 文档中位于HTML 命名空间内的元素,采用大小写不敏感的匹配。) collection = document . getElementsByTagNameNS(namespace, localName)-
如果 namespace 和 localName 都为 "
*",则返回一个HTMLCollection, 其中包含所有后代元素。如果只有 namespace 为 "
*",则返回一个HTMLCollection, 其中包含所有 后代元素中局部名称为 localName 的元素。如果只有 localName 为 "
*",则返回一个HTMLCollection, 其中包含所有 后代元素中命名空间为 namespace 的元素。否则,返回一个
HTMLCollection, 其中包含所有后代 元素中命名空间为 namespace,且 局部名称为 localName 的元素。 collection = document . getElementsByClassName(classNames)collection = element . getElementsByClassName(classNames)-
返回一个
HTMLCollection, 其中包含调用该方法的对象(一个文档或一个元素)中 拥有 classNames 指定的全部类的元素。 classNames 参数被解释为以空格分隔的 类名列表。
doctype 获取器的步骤是返回
this 中属于
文档类型的子节点;否则返回 null。
documentElement 获取器的步骤是返回
this 的文档元素。
getElementsByTagName(qualifiedName)
方法的步骤是返回 具有限定名称
qualifiedName 的元素列表,
其根为 this。
因此,在一个HTML
文档中,
document
将匹配不在
HTML 命名空间中的 <FOO> 元素,以及在
HTML 命名空间中的 <foo> 元素,但不匹配
位于HTML 命名空间中的 <FOO> 元素。
getElementsByTagNameNS(namespace, localName)
方法的步骤是返回 命名空间为 namespace 且
局部名称为
localName 的元素列表,其根为 this。
getElementsByClassName(classNames)
方法的步骤是返回 类名为 classNames 的元素列表,
其根为
this。
< div id = "example" >
< p id = "p1" class = "aaa bbb" />
< p id = "p2" class = "aaa ccc" />
< p id = "p3" class = "bbb ccc" />
</ div >
调用
document
将返回一个 HTMLCollection
其中包含两个段落
p1 和 p2。
调用
getElementsByClassName
则只会返回一个节点,即 p3。调用
document
将返回相同的结果。
调用
getElementsByClassName
不会返回任何节点;上述元素均不属于
aaa,bbb 类。
element = document . createElement(localName [, options])-
返回一个元素, 其局部名称为 localName (如果 document 是一个HTML 文档,则 localName 会转换为小写)。该 元素的命名空间在 document 是一个HTML 文档或 document 的 内容类型为 "
application/xhtml+xml" 时,是 HTML 命名空间;否则为 null。如果提供了 options,则可以使用其
customElementRegistry来 设置CustomElementRegistry。如果提供了 options,则可以使用其
is来创建一个 定制内置元素。如果 localName 不是有效的元素局部名称,则会抛出 "
InvalidCharacterError"DOMException。如果同时提供了 options 的
customElementRegistry和 options 的is, 则会抛出 "NotSupportedError"DOMException。 element = document . createElementNS(namespace, qualifiedName [, options])-
返回一个元素, 其命名空间为 namespace。其 命名空间前缀为 qualifiedName 中 U+003A (:) 之前的所有内容 或 null。其局部名称为 qualifiedName 中 U+003A (:) 之后的所有内容,或 qualifiedName 本身。
如果提供了 options,则可以使用其
customElementRegistry来 设置CustomElementRegistry。如果提供了 options,则可以使用其
is来创建一个 定制内置元素。如果 qualifiedName 不是一个(可能带有前缀的) 有效的元素局部名称,则会抛出 "
InvalidCharacterError"DOMException。如果以下任一条件为 true,则会抛出 "
NamespaceError"DOMException:- 命名空间前缀 不为 null,且 namespace 是空字符串。
- 命名空间前缀
为 "
xml",且 namespace 不是 XML 命名空间。 - qualifiedName 或
命名空间前缀
为 "
xmlns",且 namespace 不是 XMLNS 命名空间。 - namespace 是XMLNS
命名空间,且
qualifiedName 和
命名空间前缀
均不为 "
xmlns"。
如果同时提供了 options 的
customElementRegistry和 options 的is, 则会抛出 "NotSupportedError"DOMException。 documentFragment = document .createDocumentFragment()- 返回一个
DocumentFragment节点。 text = document .createTextNode(data)- 返回一个
Text节点, 其数据为 data。 text = document .createCDATASection(data)- 返回一个
CDATASection节点,其数据为 data。 comment = document .createComment(data)- 返回一个
Comment节点,其数据为 data。 processingInstruction = document .createProcessingInstruction(target, data)-
返回一个
ProcessingInstruction节点,其 目标为 target,且 数据为 data。 如果 target 不匹配Name产生式,则会抛出 "InvalidCharacterError"DOMException。 如果 data 包含 "?>",则会抛出 "InvalidCharacterError"DOMException。
对于任何 name 和
namespace,除非另有说明,否则其元素
接口为 Element。
例如,HTML 标准将定义:对于 html 和
HTML 命名空间,使用 HTMLHtmlElement
接口。[HTML]
createElement(localName, options)
方法的步骤如下:
-
如果 localName 不是一个有效的元素局部名称,则 抛出一个 "
InvalidCharacterError"DOMException。 -
如果 this 是一个HTML 文档,则将 localName 设置为 localName 的ASCII 小写形式。
-
如果 this 是一个 HTML 文档,或者 this 的内容 类型为 "
application/xhtml+xml",则令 namespace 为HTML 命名空间;否则为 null。 -
返回使用 this、 localName、 namespace、null、is、true 和 registry 创建元素的结果。
给定
document、
namespace、qualifiedName 和 options,内部
createElementNS 步骤如下:
createElementNS(namespace, qualifiedName, options)
方法的步骤是返回使用
内部 createElementNS 步骤,给定
this、
namespace、
qualifiedName 和 options 的结果。
要展平元素创建选项,给定一个字符串或
ElementCreationOptions
字典 options 和一个文档 document:
-
令 registry 为使用 document 查找自定义元素注册表的结果。
-
令 is 为 null。
-
如果 options 是一个字典:
-
如果 options["
customElementRegistry"] 存在:-
如果 is 不为 null,则抛出一个 "
NotSupportedError"DOMException。 -
将 registry 设置为 options["
customElementRegistry"]。
-
-
如果 registry 不为 null,registry 的 受作用域限制为 false,且 registry 不是 document 的自定义元素注册表,则抛出一个 "
NotSupportedError"DOMException。
-
返回 registry 和 is。
为了 Web 兼容性,允许 createElement()
和 createElementNS()
的
options
参数为字符串。
createDocumentFragment() 方法的步骤是
返回使用 this 创建文档片段的结果。
createTextNode(data) 方法的步骤是
返回使用 this 和
data 创建文本节点的结果。
createCDATASection(data) 方法的步骤
如下:
-
如果 this 是一个HTML 文档, 则抛出一个 "
NotSupportedError"DOMException。 -
如果 data 包含字符串 "
]]>",则抛出一个 "InvalidCharacterError"DOMException。 -
返回使用 this 和 data 创建 CDATA 节节点的结果。
createComment(data) 方法的步骤是
返回使用 this 和
data 创建注释节点的结果。
createProcessingInstruction(target, data)
方法的步骤是返回使用
this、
target 和 data 创建
处理指令节点的结果。
clone = document . importNode(node [, options = false])-
返回 node 的副本。如果 options 为 true,或者 options 是一个
selfOnly为 false 的字典,则该副本还包含 node 的后代。options 的
customElementRegistry可用于设置没有CustomElementRegistry的元素的注册表。如果 node 是一个文档或一个影子根,则抛出 "
NotSupportedError"DOMException。 node = document . adoptNode(node)-
将 node 从另一个文档中移入并返回该节点。
如果 node 是一个文档,则抛出 "
NotSupportedError"DOMException; 如果 node 是一个影子根,则抛出 "HierarchyRequestError"DOMException。
importNode(node, options)
方法的步骤如下:
-
如果 node 是一个文档或影子根,则抛出 一个 "
NotSupportedError"DOMException。 -
令 subtree 为 false。
-
令 registry 为 null。
-
如果 options 是布尔值,则将 subtree 设置为 options。
-
否则:
-
将 subtree 设置为以下值的逻辑非: options["
selfOnly"]。 -
如果 options["
customElementRegistry"] 存在,则将 registry 设置为该值。 -
如果 registry 的受作用域限制为 false,且 registry 不是 this 的自定义元素注册表,则 抛出一个 "
NotSupportedError"DOMException。
-
-
如果 registry 为 null,则将 registry 设置为 使用 查找自定义元素注册表, 给定 this 的结果。
-
返回使用 node 克隆节点的结果,其中 document 设置为 this, subtree 设置为 subtree,且 fallbackRegistry 设置为 registry。
要将一个节点 node 收养到一个 文档 document 中:
-
令 oldDocument 为 node 的节点文档。
-
如果 document 不是 oldDocument,则对于 node 的包含影子树且包含自身的 后代中的每个 inclusiveDescendant, 按包含影子树的树顺序:
-
将 inclusiveDescendant 的节点文档 设置为 document。
-
如果 inclusiveDescendant 是一个影子根,并且 满足以下任一 条件:
-
inclusiveDescendant 的自定义元素注册表 为 null, 且 inclusiveDescendant 的保持自定义 元素注册表为 null为 false;或者
-
inclusiveDescendant 的自定义元素注册表 是全局自定义元素 注册表。
则将 inclusiveDescendant 的自定义元素注册表设置为 document 的自定义元素注册表的 有效全局自定义 元素注册表。
-
-
否则,如果 inclusiveDescendant 是一个元素:
-
如果 inclusiveDescendant 的自定义元素注册表为 null,或者 inclusiveDescendant 的自定义元素注册表的 受作用域限制为 false:
-
令 registry 为 null。
-
如果 inclusiveDescendant 的自定义元素 注册表不为 null,且 inclusiveDescendant 的父节点为 null,或者 inclusiveDescendant 的父节点是一个 专属
DocumentFragment节点,则将 registry 设置为 document 的自定义元素 注册表。 -
否则,将 registry 设置为 使用 inclusiveDescendant 的 父节点 查找自定义 元素注册表的结果。
-
将 inclusiveDescendant 的自定义元素 注册表设置为 registry 的有效 全局自定义元素注册表。
-
-
如果 inclusiveDescendant 是自定义的,则 入队一个自定义 元素回调反应,参数为 inclusiveDescendant、回调 名称 "
adoptedCallback",以及 « oldDocument、 document »。
-
使用 inclusiveDescendant 和 oldDocument 运行收养步骤。
-
adoptNode(node) 方法的步骤如下:
-
如果 node 是一个文档,则抛出一个 "
NotSupportedError"DOMException。 -
如果 node 是一个影子根,则抛出一个 "
HierarchyRequestError"DOMException。 -
返回 node。
当 null 或一个 CustomElementRegistry
对象 registry 不为 null,且
registry 的受
作用域限制为 false 时,称其是一个
全局自定义元素注册表。
对于 null 或一个 CustomElementRegistry
对象 registry,其
有效全局自定义元素注册表为:
-
如果 registry 是一个全局自定义元素注册表,则 返回 registry。
-
返回 null。
createAttribute(localName) 方法的
步骤如下:
-
如果 localName 不是一个有效的属性局部名称,则 抛出一个 "
InvalidCharacterError"DOMException。 - 如果 this 是 一个HTML 文档,则将 localName 设置为 localName 的ASCII 小写形式。
createAttributeNS(namespace, qualifiedName)
方法的步骤如下:
-
令(namespace、prefix、localName)为 使用 "
attribute" 验证 并提取 namespace 和 qualifiedName 的结果。
createEvent(interface) 方法的步骤
如下:
-
令 constructor 为 null。
-
如果 interface 与下表第一列中的任何字符串进行ASCII 大小写不敏感匹配, 则将 constructor 设置为与匹配字符串处于同一行的 第二列中的接口:
字符串 接口 备注 " beforeunloadevent"BeforeUnloadEvent[HTML] " compositionevent"CompositionEvent[UIEVENTS] " customevent"CustomEvent" devicemotionevent"DeviceMotionEvent[DEVICE-ORIENTATION] " deviceorientationevent"DeviceOrientationEvent" dragevent"DragEvent[HTML] " event"Event" events"" focusevent"FocusEvent[UIEVENTS] " hashchangeevent"HashChangeEvent[HTML] " htmlevents"Event" keyboardevent"KeyboardEvent[UIEVENTS] " messageevent"MessageEvent[HTML] " mouseevent"MouseEvent[UIEVENTS] " mouseevents"" storageevent"StorageEvent[HTML] " svgevents"Event" textevent"TextEvent[UIEVENTS] " touchevent"TouchEvent[TOUCH-EVENTS] " uievent"UIEvent[UIEVENTS] " uievents" -
如果 constructor 为 null,则抛出一个 "
NotSupportedError"DOMException。 -
如果 constructor 指示的接口未在 相关全局对象上暴露,该对象属于 this,则抛出一个 "
NotSupportedError"DOMException。通常,用户代理会在某些配置下禁用触摸事件支持, 在这种情况下, 此条款会针对
TouchEvent接口触发。 -
令 event 为使用 constructor 创建事件的结果。
-
将 event 的
type属性初始化为空字符串。 -
将 event 的
timeStamp属性初始化为使用 相关全局对象调用 当前高精度时间的结果,该对象属于 this。 -
将 event 的
isTrusted属性初始化为 false。 -
清除 event 的已初始化标志。
-
返回 event。
应当改用Event 构造器。
createRange() 方法的步骤是返回一个新的
活跃范围,以(this,0)作为
其起点和终点。
也可以使用 Range()
构造器。
createNodeIterator(root, whatToShow, filter)
方法的步骤如下:
-
令 iterator 为一个新的
NodeIterator对象。 -
将 iterator 的根设置为 root。
-
将 iterator 的引用设置为(root,true)。
-
将 iterator 的whatToShow 设置为 whatToShow。
-
将 iterator 的过滤器设置为 filter。
-
返回 iterator。
createTreeWalker(root, whatToShow, filter)
方法的步骤如下:
-
令 walker 为一个新的
TreeWalker对象。 -
将 walker 的whatToShow 设置为 whatToShow。
-
将 walker 的过滤器设置为 filter。
- 返回 walker。
4.5.1.接口 DOMImplementation
用户代理必须创建一个 DOMImplementation
对象,每当一个 文档 被
创建时,并将其关联到该 文档。
[Exposed =Window ]interface { [DOMImplementation NewObject ]DocumentType createDocumentType (DOMString ,name DOMString ,publicId DOMString ); [systemId NewObject ]XMLDocument createDocument (DOMString ?, [namespace LegacyNullToEmptyString ]DOMString ,qualifiedName optional DocumentType ?=doctype null ); [NewObject ]Document createHTMLDocument (optional DOMString );title boolean hasFeature (); // 历史遗留;始终返回 true };
doctype = document .implementation.createDocumentType(name, publicId, systemId)-
返回一个 文档类型,
具有给定的 name、publicId 和 systemId。
如果 name 不是一个 有效的文档类型名称,则一个 "
InvalidCharacterError"DOMException将被抛出。 doc = document .implementation. createDocument(namespace, qualifiedName [, doctype = null])-
返回一个
XMLDocument, 具有一个 文档元素 其 局部名称 为 qualifiedName,且其 命名空间 为 namespace(除非 qualifiedName 是 空字符串),并且以 doctype(如果给定)作为其 文档类型。此方法抛出的异常与
createElementNS()方法相同,当该方法 使用 namespace 和 qualifiedName 调用时。 doc = document .implementation. createHTMLDocument([title])-
返回一个 文档,
具有一棵基本的
树,该树已构建完成,
包含一个
title元素,除非 title 参数被省略。
此
createDocumentType(name, publicId, systemId)
方法的步骤如下:
-
如果 name 不是一个 有效的文档类型名称,则抛出一个 "
InvalidCharacterError"DOMException。
此
createDocument(namespace, qualifiedName, doctype)
方法的步骤如下:
-
令 document 为 创建文档 的结果,该文档实现
XMLDocument, 给定 this 的 相关领域。 -
令 element 为 null。
-
如果 qualifiedName 不是空字符串,则将 element 设置为 运行 内部
createElementNS步骤 的结果, 给定 document、namespace、qualifiedName 和一个空字典。 -
如果 doctype 非 null,则 追加 doctype 到 document。
-
如果 element 非 null,则 追加 element 到 document。
-
document 的 内容类型 由以下值决定: namespace:
-
返回 document。
此
createHTMLDocument(title)
方法的步骤如下:
-
令 doctype 为 创建文档类型 的结果,给定 doc 和 "
html"。 -
追加 doctype 到 doc。
-
追加 以下 操作的结果:创建元素,给定 doc、 "
head" 和 HTML 命名空间,追加到html元素(先前创建的)。 -
如果给定了 title:
-
追加 以下 操作的结果:创建元素,给定 doc、 "
body" 和 HTML 命名空间,追加到html元素(先前创建的)。 -
返回 doc。
此 hasFeature() 方法的步骤是
返回 true。
hasFeature()
最初用于报告用户代理是否
声称支持给定的 DOM 特性,但实践证明,它远不如
简单地检查所需的对象、属性或
方法是否存在那样可靠或精细。因此,不应再使用它,但它仍然存在(并且只是
返回 true),以免旧页面停止工作。
4.6.
接口DocumentType
[Exposed =Window ]interface :DocumentType Node {readonly attribute DOMString name ;readonly attribute DOMString publicId ;readonly attribute DOMString systemId ; };
DocumentType
节点 简称为
文档类型。
文档类型 具有 关联的 名称(一个字符串)、 公共 ID(一个字符串)和 系统 ID(一个字符串)。
要 创建文档类型 给定一个 文档 document、一个字符串 name,以及可选的字符串 publicId(默认为空字符串)和字符串 systemId(默认为空字符串):
-
令 doctype 为 创建节点 的结果,该节点实现
DocumentType, 给定 document。 -
将 doctype 的 名称 设置为 name,将 公共 ID 设置为 publicId,并将 系统 ID 设置为 systemId。
-
返回 doctype。
此 publicId 获取器的步骤是返回
this 的 公共
ID。
此 systemId 获取器的步骤是返回
this 的 系统
ID。
4.7.
接口DocumentFragment
[Exposed =Window ]interface :DocumentFragment Node {constructor (); };
tree = newDocumentFragment()- 返回一个新的
DocumentFragment节点。
一个专属 DocumentFragment
节点是一个DocumentFragment
节点,但不是ShadowRoot
节点。
一个DocumentFragment
节点有一个关联的
宿主(null 或一个
位于不同节点树中的元素)。除非
另有说明,否则为 null。
一个对象 A 是一个 包含宿主且包含自身的祖先, 对于对象 B 而言,如果 A 是 B 的包含自身的 祖先, 或者 B 的根具有非 null 的宿主,且 A 是包含宿主且包含自身的祖先, 对于 B 的根的 宿主而言。
DocumentFragment
节点的宿主
概念对于 HTML 的
template
元素和影子根很有用,并会影响
预插入
和替换
算法。
要 创建一个
文档片段,给定一个 文档
document:返回 创建节点 的结果,该节点实现
DocumentFragment,
给定 document。
此
new DocumentFragment()
构造函数的步骤是将 this 的 节点文档 设置为
当前全局对象 的 关联的 Document。
4.8. 接口 ShadowRoot
[Exposed =Window ]interface :ShadowRoot DocumentFragment {readonly attribute ShadowRootMode mode ;readonly attribute boolean delegatesFocus ;readonly attribute boolean serializable ;readonly attribute SlotAssignmentMode slotAssignment ;readonly attribute boolean clonable ;readonly attribute Element host ;attribute EventHandler onslotchange ; };enum {ShadowRootMode ,"open" };"closed" enum {SlotAssignmentMode ,"manual" };"named"
ShadowRoot
节点简称为
影子根节点。
影子根节点具有
关联的模式("open"
或 "closed")。
影子根节点具有 关联的委托焦点 (一个布尔值)。其初始值为 false。
影子根节点具有 关联的 可供元素内部使用(一个布尔值)。其 初始值为 false。
影子根节点具有 关联的声明式 (一个布尔值)。其初始值为 false。
影子根节点具有 关联的可序列化(一个布尔值)。 其初始值为 false。
影子根节点具有
关联的插槽分配
("manual" 或 "named")。
影子根节点具有 关联的可克隆(一个布尔值)。 其初始值为 false。
影子根节点具有
关联的自定义元素注册表
(null 或一个 CustomElementRegistry
对象)。其初始值为 null。
影子根节点具有 关联的 保持自定义元素注册表为 null(一个布尔值)。 其初始值为 false。
此值只能与声明式影子根节点同时为 true。并且只有当 影子根节点的自定义 元素注册表 为 null 时,此值才有意义。
一个影子根节点的获取父节点算法, 给定 event,如果 event 的组合标志未设置,且该影子根节点是 event 的路径中第一个事件路径项的 调用目标的根节点,则返回 null;否则返回该影子根节点的 宿主。
此 delegatesFocus 获取器的步骤是返回
this 的 委托焦点。
此 serializable 获取器的步骤是返回
this 的 可序列化。
此 slotAssignment 获取器的步骤是返回
this 的 插槽
分配。
此 clonable 获取器的步骤是返回
this 的 可克隆。
onslotchange 属性是
onslotchange 事件处理器的
事件处理器 IDL 属性,其
事件处理器事件类型为 slotchange。
包含影子树的树顺序是对一棵 节点树进行的包含影子树的前序深度优先 遍历。 对一棵节点树 tree 进行包含影子树的前序深度优先 遍历,即对 tree 进行前序深度优先遍历,并且对于 在 tree 中遇到的每个影子宿主, 在遇到它之后,立即对该元素的 影子根节点的节点树进行包含影子树的前序深度优先 遍历。
一个对象的包含影子树的根节点是其 根节点的宿主的包含影子树的 根节点,如果该 对象的根节点是一个影子根节点; 否则为其根节点。
对象 A 是对象 B 的包含影子树的后代, 如果 A 是 B 的后代,或者 A 的 根节点是一个影子根节点,且 A 的根节点的 宿主是 B 的包含影子树且包含自身的后代。
一个 包含影子树且包含自身的后代 是对象自身或其包含影子树的后代之一。
对象 A 是对象 B 的包含影子树的祖先, 当且仅当 B 是 A 的包含影子树的后代。
一个 包含影子树且包含自身的祖先 是对象自身或其包含影子树的祖先之一。
一个节点 A 相对于 一个节点 B 是闭合影子树隐藏的,如果以下所有条件均为 true:
要以对象 B 为参照,对对象 A 进行重定向, 请重复以下步骤,直到返回一个对象:
-
如果以下任一条件为 true
则返回 A。
重定向 算法由事件分派以及 其他规范(例如 全屏)使用。[FULLSCREEN]
4.9. 接口 Element
[Exposed =Window ]interface :Element Node {readonly attribute DOMString ?namespaceURI ;readonly attribute DOMString ?prefix ;readonly attribute DOMString localName ;readonly attribute DOMString tagName ; [CEReactions ]attribute DOMString id ; [CEReactions ]attribute DOMString className ; [SameObject ,PutForwards =value ]readonly attribute DOMTokenList classList ; [CEReactions ,Unscopable ]attribute DOMString slot ;boolean hasAttributes (); [SameObject ]readonly attribute NamedNodeMap attributes ;sequence <DOMString >getAttributeNames ();DOMString ?getAttribute (DOMString );qualifiedName DOMString ?getAttributeNS (DOMString ?,namespace DOMString ); [localName CEReactions ]undefined setAttribute (DOMString , (qualifiedName TrustedType or DOMString )); [value CEReactions ]undefined setAttributeNS (DOMString ?,namespace DOMString , (qualifiedName TrustedType or DOMString )); [value CEReactions ]undefined removeAttribute (DOMString ); [qualifiedName CEReactions ]undefined removeAttributeNS (DOMString ?,namespace DOMString ); [localName CEReactions ]boolean toggleAttribute (DOMString ,qualifiedName optional boolean );force boolean hasAttribute (DOMString );qualifiedName boolean hasAttributeNS (DOMString ?,namespace DOMString );localName Attr ?getAttributeNode (DOMString );qualifiedName Attr ?getAttributeNodeNS (DOMString ?,namespace DOMString ); [localName CEReactions ]Attr ?setAttributeNode (Attr ); [attr CEReactions ]Attr ?setAttributeNodeNS (Attr ); [attr CEReactions ]Attr removeAttributeNode (Attr );attr ShadowRoot attachShadow (ShadowRootInit );init readonly attribute ShadowRoot ?shadowRoot ;readonly attribute CustomElementRegistry ?customElementRegistry ;Element ?closest (DOMString );selectors boolean matches (DOMString );selectors boolean webkitMatchesSelector (DOMString ); // legacy alias of .matchesselectors HTMLCollection getElementsByTagName (DOMString );qualifiedName HTMLCollection getElementsByTagNameNS (DOMString ?,namespace DOMString );localName HTMLCollection getElementsByClassName (DOMString ); [classNames CEReactions ]Element ?insertAdjacentElement (DOMString ,where Element ); // legacyelement undefined insertAdjacentText (DOMString ,where DOMString ); // legacy };data dictionary {ShadowRootInit required ShadowRootMode ;mode boolean =delegatesFocus false ;boolean =serializable false ;SlotAssignmentMode = "named";slotAssignment boolean =clonable false ;CustomElementRegistry ?; };customElementRegistry
ShadowRootInit
比较特殊,它允许将 undefined 和
null 都传递给其customElementRegistry
成员,以允许 Web
开发者将一个ShadowRoot
节点而不是字典传递给attachShadow()。
元素具有以下 关联属性:
- 命名空间
- Null 或一个非空字符串。
- 命名空间前缀
- Null 或一个非空字符串。
- 本地名称
- 一个非空字符串。
- 自定义元素注册表
- Null 或一个
CustomElementRegistry对象。 - 自定义元素状态
- "
undefined"、"failed"、"uncustomized"、 "precustomized" 或 "custom"。 - 自定义元素定义
- Null 或一个自定义元素定义。
is值- Null 或一个有效的自定义元素名称。
如果一个元素的自定义元素状态为
"uncustomized" 或 "custom",则称其为
已定义。如果一个元素的
自定义元素状态为 "custom",则称其为
自定义的。
元素是否已定义用于确定
:defined
伪类的行为。元素是否为自定义的则
用于确定变更算法的行为。
"failed" 和 "precustomized" 状态用于确保,如果
自定义元素构造函数首次执行失败,
就不会再通过
升级再次执行它。
以下代码展示处于这四种状态的元素:
<!DOCTYPE html>
< script >
window. customElements. define( "sw-rey" , class extends HTMLElement {})
window. customElements. define( "sw-finn" , class extends HTMLElement {}, { extends : "p" })
window. customElements. define( "sw-kylo" , class extends HTMLElement {
constructor () {
// 此示例中有意省略 super()
}
})
</ script >
<!-- "undefined"(未定义,非自定义)-->
< sw-han ></ sw-han >
< p is = "sw-luke" ></ p >
< p is = "asdf" ></ p >
<!-- "failed"(未定义,非自定义)-->
< sw-kylo ></ sw-kylo >
<!-- "uncustomized"(已定义,非自定义)-->
< p ></ p >
< asdf ></ asdf >
<!-- "custom"(已定义,自定义)-->
< sw-rey ></ sw-rey >
< p is = "sw-finn" ></ p >
元素还具有一个 关联的 影子根(null 或一个 影子根)。除非 另有说明,否则它为 null。如果一个元素的 影子根非 null,则称该元素为影子宿主。
一个元素的
限定名称是其
本地
名称,如果其命名空间前缀为 null;否则为其
命名空间前缀,后跟 ":",
再后跟其
本地
名称。
一个元素的HTML 大写限定名称是以下步骤的 返回值:
用户代理可以通过将限定名称和 HTML 大写限定名称存储在 内部槽中来优化它们。
要创建一个
元素,给定一个文档
document、字符串 localName、字符串或 null namespace,以及
可选的字符串或 null prefix(默认为 null)、字符串或 null is(默认为
null)、布尔值 synchronousCustomElements(默认为 false),以及 "default"、
null 或一个CustomElementRegistry
对象 registry(默认为 "default"):
-
令 result 为 null。
-
如果 registry 为 "
default",则将 registry 设置为 给定 document,查找自定义元素注册表的结果。 -
令 definition 为 给定 registry、 namespace、localName 和 is, 查找自定义元素定义的结果。
-
如果 definition 非 null,且 definition 的 名称不等于其 本地名称(即 definition 表示一个 自定义内置元素):
-
将 result 设置为给定 document、interface、localName、HTML 命名空间、 prefix、"
undefined"、is 和 registry, 在内部创建元素的结果。 -
如果 synchronousCustomElements 为 true,则执行此步骤并捕获任何 异常:
-
使用 definition 升级 result。
如果此步骤抛出了异常 exception:
-
-
否则,给定 result 和 definition,将自定义元素 升级反应加入队列。
-
否则,如果 definition 非 null:
-
如果 synchronousCustomElements 为 true:
-
令 C 为 definition 的 构造函数。
-
令 previousRegistry 为周边代理的 活动自定义元素 构造函数映射[C], 默认值为 null。
-
将周边代理的 活动自定义元素 构造函数映射[C] 设置为 registry。
-
执行以下步骤并捕获任何异常:
-
将 result 设置为不带 参数构造 C 的结果。
-
断言:以下条件之一成立:
-
IDL 确保 result 是一个
HTMLElement对象,而这些对象都 使用HTML 命名空间。 -
如果 result 的属性列表非空, 则抛出一个 "
NotSupportedError"DOMException。 -
如果 result 具有子节点,则抛出一个 "
NotSupportedError"DOMException。 -
如果 result 的父节点非 null,则抛出一个 "
NotSupportedError"DOMException。 -
如果 result 的节点文档不是 document,则 抛出一个 "
NotSupportedError"DOMException。 -
如果 result 的本地名称不 等于 localName,则抛出一个 "
NotSupportedError"DOMException。 -
将 result 的命名空间前缀 设置为 prefix。
-
将 result 的
is值设置为 null。 -
将 result 的自定义元素 注册表设置为 registry。
如果上述任一步骤抛出异常 exception:
-
-
如果 previousRegistry 为 null,则移除 周边代理的 活动自定义元素 构造函数映射[C]。
-
否则,将周边代理的 活动自定义元素 构造函数映射[C] 设置为 previousRegistry。
-
-
否则:
-
将 result 设置为给定 document、
HTMLElement、 localName、HTML 命名空间、 prefix、"undefined"、null 和 registry, 在内部创建元素的结果。 -
给定 result 和 definition,将自定义元素 升级反应加入队列。
-
-
-
否则:
-
令 interface 为 localName 和 namespace 对应的元素接口。
-
将 result 设置为给定 document、interface、localName、namespace、 prefix、"
uncustomized"、is 和 registry, 在内部创建元素的结果。 -
如果 namespace 为HTML 命名空间,且 localName 是一个 有效的自定义元素名称,或者 is 非 null,则将 result 的 自定义元素状态设置为 "
undefined"。
-
-
返回 result。
要在内部创建
元素,给定一个文档
document、一个
接口 interface、字符串 localName、字符串或 null namespace、
字符串或 null prefix、字符串 state、字符串或 null is,以及
null 或一个CustomElementRegistry
对象 registry:
元素还具有一个
属性列表,它是一个通过
NamedNodeMap
暴露的列表。
除非在创建
元素时明确提供,否则其
属性
列表为空。
如果一个元素的 具有一个属性 A,则其属性列表必须包含 A。
本规范和其他规范可以为 元素定义 属性变更步骤。该算法 接收 element、localName、 oldValue、value 和 namespace。
要为一个属性 attribute 处理属性 变更,给定 element、oldValue 和 newValue,执行以下步骤:
-
为 element 将一个 变更记录加入队列,类型为 "
attributes",并传入 attribute 的本地名称、attribute 的 命名空间、oldValue、« »、« »、null 和 null。 -
如果 element 是自定义的,则 将一个自定义元素回调 反应加入队列,传入 element,回调名称为 "
attributeChangedCallback",参数为 « attribute 的本地名称、 oldValue、newValue、attribute 的命名空间 »。 -
使用 element、attribute 的 本地名称、oldValue、 newValue 和 attribute 的 命名空间执行属性变更步骤。
要将一个属性 attribute 更改为 value:
要移除一个 属性 attribute:
要按名称获取属性,给定一个 字符串 qualifiedName 和一个元素 element:
要 按命名空间和本地名称获取属性, 给定 null 或字符串 namespace、字符串 localName 和一个 元素 element:
要获取 属性值,给定一个 元素 element、字符串 localName 和一个可选的 null 或 字符串 namespace(默认为 null):
要设置一个 属性,给定一个 属性 attr 和一个元素 element:
-
令 verifiedValue 为调用 获取符合可信类型要求的属性 值的结果,传入 attr 的 本地名称、attr 的命名空间、element 和 attr 的值。[TRUSTED-TYPES]
-
如果 attr 的元素既不是 null 也不是 element, 则抛出一个 "
InUseAttributeError"DOMException。 -
如果 oldAttr 是 attr,则返回 attr。
-
将 attr 的值设置为 verifiedValue。
-
如果 oldAttr 非 null,则以 attr 替换 oldAttr。
-
否则,将 attr 追加到 element。
-
返回 oldAttr。
要设置 属性值,给定一个 元素 element、字符串 localName、字符串 value、 可选的 null 或字符串 prefix(默认为 null),以及可选的 null 或字符串 namespace(默认为 null):
要按名称移除属性, 给定字符串 qualifiedName 和一个元素 element:
要 按命名空间和本地 名称移除属性, 给定 null 或字符串 namespace、字符串 localName 和一个 元素 element:
一个元素可以有一个 关联的 唯一标识符(ID)
历史上,元素可以有多个标识符,例如同时使用
HTML id 属性和 DTD。本规范将ID
定义为 DOM 的一个概念,并规定每个元素只能有一个,由
id 属性给出。
-
如果 localName 为
id、namespace 为 null,且 value 为 null 或空字符串,则取消设置 element 的 ID。 -
否则,如果 localName 为
id且 namespace 为 null,则 将 element 的ID 设置为 value。
虽然本规范为任何元素上的 class、
id 和 slot 属性定义了要求,但并未断言在任何元素上
使用这些属性是否符合规范。
一个节点的父节点如果是
Element 类型,则称为
其
父元素。如果该节点具有
不同类型的父节点,则其
父元素为 null。
- namespace = element .
namespaceURI - 返回命名空间。
- prefix = element .
prefix - 返回 命名空间前缀。
- localName = element .
localName - 返回 本地名称。
- qualifiedName = element .
tagName - 返回HTML 大写限定名称。
此 namespaceURI 获取器的步骤是返回
this 的 命名空间。
此 prefix 获取器的步骤是返回
this 的 命名空间前缀。
此 localName 获取器的步骤是返回
this 的 局部
名称。
此 tagName 获取器的步骤是返回
this 的 HTML 大写限定名称。
element . id [ = value ]-
返回 element 的
id内容属性的值。可以通过设置来 更改它。 element . className [ = value ]-
返回 element 的
class内容属性的值。可以设置 以更改它。 element . classList-
允许将 element 的
class内容属性作为一个 由空白分隔的词元集合进行操作,通过一个DOMTokenList对象。 element . slot [ = value ]-
返回 element 的
slot内容属性的值。可以通过设置来 更改它。
被定义为 反映 字符串 name 的 IDL 属性,必须具有以下获取器和设置器步骤:
此 id 属性必须 反映
"id"。
此 className 属性必须
反映
"class"。
此 classList 获取器的步骤是返回一个
DOMTokenList
对象,其关联的 元素 是 this,且其关联的
属性 的 局部名称 是 class。此 词元集合,属于这个
特定的 DOMTokenList
对象,也称为该 元素 的
类。
此 slot 属性必须 反映
"slot"。
id、class 和 slot 实际上是
超全局属性,因为它们可以出现在任何元素上,而不论该元素的
命名空间是什么。
element . hasAttributes()-
如果 element 具有属性,则返回 true;否则返回 false。
element . getAttributeNames()element . getAttribute(qualifiedName)-
返回 element 的第一个 属性,其 限定名称 为 qualifiedName;如果没有这样的 属性,则返回 null。
element . getAttributeNS(namespace, localName)-
返回 element 的 属性,其 命名空间 为 namespace 且 局部名称 为 localName;否则返回 null,如果 不存在 这样的 属性。
element . setAttribute(qualifiedName, value)element . setAttributeNS(namespace, localName, value)-
设置 值,属于 element 的 属性,其 命名空间 为 namespace 且 局部名称 为 localName,设置为 value。
element . removeAttribute(qualifiedName)element . removeAttributeNS(namespace, localName)element . toggleAttribute(qualifiedName [, force])-
如果未给定 force,则“切换” qualifiedName,在它 存在时将其移除,不存在时将其添加。如果 force 为 true,则添加 qualifiedName。如果 force 为 false,则移除 qualifiedName。
如果 qualifiedName 现在存在,则返回 true;否则返回 false。
element . hasAttribute(qualifiedName)-
返回 true,如果 element 具有一个 属性,其 限定名称 为 qualifiedName; 否则返回 false。
element . hasAttributeNS(namespace, localName)-
返回 true,如果 element 具有一个 属性,其 命名空间 为 namespace 且 局部名称 为 localName。
此 attributes 获取器的步骤是返回
关联的 NamedNodeMap。
此 getAttribute(qualifiedName) 方法
的步骤如下:
此
getAttributeNS(namespace, localName)
方法的步骤如下:
此
setAttribute(qualifiedName, value)
方法的步骤如下:
-
如果 qualifiedName 不是一个 有效的属性局部名称,则 抛出 一个 "
InvalidCharacterError"DOMException。尽管参数如此命名, qualifiedName 仅用作 限定名称,当一个 属性 已经 以该限定名称存在时。否则,它用作 局部 名称,属于新 属性。我们只需针对后一种情况验证它。
-
如果 this 位于 HTML 命名空间 中,且其 节点文档 是一个 HTML 文档, 则将 qualifiedName 设置为 qualifiedName 的 ASCII 小写 形式。
-
令 verifiedValue 为调用以下算法的结果: 获取符合可信类型的 属性值,使用 qualifiedName、null、this, 和 value。[TRUSTED-TYPES]
-
令 attribute 为第一个 属性,位于 this 的 属性列表 中,其 限定名称 为 qualifiedName, 否则为 null。
-
如果 attribute 非 null,则 更改 attribute 为 verifiedValue 并返回。
-
将 attribute 设置为 创建属性 的结果,给定 this 的 节点 文档、qualifiedName、null、null 和 verifiedValue。
此
setAttributeNS(namespace, qualifiedName, value)
方法的步骤如下:
-
令 (namespace, prefix, localName) 为以下操作的结果: 验证并提取 namespace 和 qualifiedName,给定 "
attribute"。 -
令 verifiedValue 为调用以下算法的结果: 获取符合可信类型的 属性值,使用 localName、namespace、 this 和 value。[TRUSTED-TYPES]
-
设置属性值,针对 this 使用 localName、 verifiedValue、prefix 和 namespace。
此 hasAttribute(qualifiedName) 方法
的步骤如下:
此
toggleAttribute(qualifiedName, force)
方法的步骤如下:
-
如果 qualifiedName 不是一个 有效的属性局部名称,则 抛出 一个 "
InvalidCharacterError"DOMException。请参阅 上面的讨论 了解为何 我们将其作为局部名称而非限定名称进行验证。
-
如果 this 位于 HTML 命名空间 中,且其 节点文档 是一个 HTML 文档, 则将 qualifiedName 设置为 qualifiedName 的 ASCII 小写 形式。
-
令 attribute 为第一个 属性,位于 this 的 属性列表 中,其 限定名称 为 qualifiedName, 否则为 null。
-
如果 attribute 为 null:
-
如果未给定 force 或其为 false, 移除属性,给定 qualifiedName 和 this,然后返回 false。
-
返回 true。
此
hasAttributeNS(namespace, localName)
方法的步骤如下:
此 removeAttributeNode(attr) 方法
的步骤
如下:
-
如果 this 的 属性列表 不 包含 attr,则 抛出 一个 "
NotFoundError"DOMException。 -
移除 attr。
-
返回 attr。
shadow = element .attachShadow(init)-
创建一个 影子根,供 element 使用,并返回它。
shadow = element .shadowRoot
一个 有效的影子宿主 名称 是:
- 一个 有效的自定义元素名称
- "
article"、 "aside"、 "blockquote"、 "body"、 "div"、 "footer"、 "h1"、 "h2"、 "h3"、 "h4"、 "h5"、 "h6"、 "header"、 "main"、 "nav"、 "p"、 "section" 或 "span"
此列表有意受到限制,以便内置元素可以获得内部 影子树,随着 时间推移按需添加。
此 attachShadow(init) 方法的步骤如下:
-
如果 init["
customElementRegistry"] 存在,则 将 registry 设置为它。 -
如果 registry 非 null,registry 的 是否限定作用域 为 false,且 registry 不是 this 的 节点 文档 的 自定义元素注册表,则 抛出 一个 "
NotSupportedError"DOMException。 -
运行 附加影子根,使用 this、 init["
mode"], init["delegatesFocus"], init["serializable"], init["slotAssignment"], init["clonable"], 和 registry。
要 附加一个
影子根,给定一个 元素
element、一个字符串 mode、一个布尔值 delegatesFocus、一个布尔值
serializable、一个字符串 slotAssignment、一个布尔值 clonable,以及 null
或一个 CustomElementRegistry
对象 registry:
-
如果 element 的 命名空间 不是 HTML 命名空间, 则 抛出 一个 "
NotSupportedError"DOMException。 -
如果 element 的 局部名称 不是一个 有效的 影子宿主名称,则 抛出 一个 "
NotSupportedError"DOMException。 -
如果 element 的 局部名称 是一个 有效的自定义元素名称,或者 element 的
is值 非 null:-
令 definition 为 查找自定义元素 定义 的结果, 给定 element 的 自定义元素注册表、其 命名空间、其 局部 名称,以及其
is值。 -
如果 definition 非 null 且 definition 的 禁用影子 为 true,则 抛出 一个 "
NotSupportedError"DOMException。
-
-
如果 element 是一个 影子宿主:
-
令 currentShadowRoot 为 element 的 影子根。
-
如果以下任一条件为真:
则 抛出 一个 "
NotSupportedError"DOMException。 -
将 currentShadowRoot 的 声明式 设置为 false。
-
返回。
-
-
令 shadow 为 创建节点 的结果,该节点实现
ShadowRoot, 给定 element 的 节点文档。 -
将 shadow 的 宿主 设置为 element。
-
将 shadow 的 模式 设置为 mode。
-
将 shadow 的 委托焦点 设置为 delegatesFocus。
-
如果 element 的 自定义元素状态 是 "
precustomized" 或 "custom",则将 shadow 的 可供元素内部机制使用 设置为 true。 -
将 shadow 的 声明式 设置为 false。
-
将 shadow 的 可序列化 设置为 serializable。
-
将 shadow 的 插槽分配 设置为 slotAssignment。
-
将 shadow 的 可克隆 设置为 clonable。
-
将 shadow 的 自定义元素注册表 设置为 registry。
-
将 element 的 影子根 设置为 shadow。
此 shadowRoot 获取器的步骤如下:
registry = element .customElementRegistry-
返回 element 的
CustomElementRegistry对象(如果存在);否则返回 null。
element .closest(selectors)- 返回第一个(从 element 开始) 包含自身的祖先,其匹配 selectors,否则返回 null。
element .matches(selectors)- 返回 true,如果将 selectors 与 element 的 根 进行匹配 得到 element;否则返回 false。
此 closest(selectors) 方法的步骤如下:
-
令 selector 为 解析选择器 的结果,来源为 selectors。 [SELECTORS4]
-
如果 selector 为失败,则 抛出 一个 "
SyntaxError"DOMException。 -
对于 elements 中的每个 element:如果 将选择器与元素进行匹配, 使用 selector、element 和 作用域根 this,返回成功, 则返回 element。[SELECTORS4]
-
返回 null。
此 matches(selectors) 和
webkitMatchesSelector(selectors)
方法的步骤
如下:
-
令 selector 为 解析选择器 的结果,来源为 selectors。 [SELECTORS4]
-
如果 selector 为失败,则 抛出 一个 "
SyntaxError"DOMException。 -
如果以下操作的结果:将选择器与元素进行匹配, 使用 selector、 this 和 作用域 根 this,返回成功,则返回 true;否则, 返回 false。[SELECTORS4]
此 getElementsByTagName(qualifiedName)
方法的步骤是返回 元素列表,其限定名称为
qualifiedName
针对 this。
此
getElementsByTagNameNS(namespace, localName)
方法的步骤是返回 元素列表,其命名空间为 namespace 且
局部
名称为 localName,针对 this。
此 getElementsByClassName(classNames)
方法的步骤是返回 类名为 classNames 的元素列表
针对
this。
要 相邻插入, 给定一个 元素 element、字符串 where 和一个 节点 node,运行与第一个 ASCII 不区分大小写 匹配 where 的项关联的步骤:
- "
beforebegin" -
如果 element 的 父节点 为 null,则返回 null。
- "
afterbegin" - "
beforeend" -
返回 预插入 node 到 element 的结果, 位于以下值之前: null。
- "
afterend" -
如果 element 的 父节点 为 null,则返回 null。
返回 预插入 node 的结果,插入到 element 的 父节点 中,位于 element 的 下一个兄弟节点 之前。
- 否则
-
抛出 一个 "
SyntaxError"DOMException。
此
insertAdjacentElement(where, element)
方法的步骤是返回运行 相邻插入 的结果,给定 this、
where 和 element。
此
insertAdjacentText(where, data)
方法的步骤如下:
此方法不返回任何值,因为在我们有机会设计它之前,它就已经存在了。
4.9.1.
接口 NamedNodeMap
[Exposed =Window ,LegacyUnenumerableNamedProperties ]interface {NamedNodeMap readonly attribute unsigned long length ;getter Attr ?item (unsigned long );index getter Attr ?getNamedItem (DOMString );qualifiedName Attr ?getNamedItemNS (DOMString ?,namespace DOMString ); [localName CEReactions ]Attr ?setNamedItem (Attr ); [attr CEReactions ]Attr ?setNamedItemNS (Attr ); [attr CEReactions ]Attr removeNamedItem (DOMString ); [qualifiedName CEReactions ]Attr removeNamedItemNS (DOMString ?,namespace DOMString ); };localName
一个 NamedNodeMap
有一个关联的
元素(一个
元素)。
一个 NamedNodeMap
对象的
属性列表是其
元素的
属性
列表。
一个 NamedNodeMap
对象的支持的属性索引是从零到其
属性列表的大小 − 1 范围内的数字,除非
该属性列表为空,在这种
情况下不存在
支持的属性索引。
item(index) 方法步骤如下:
一个 NamedNodeMap
对象的 支持的属性名称 是运行
以下
步骤的返回值:
-
令 names 为 限定名称,属于这些 属性 位于此
NamedNodeMap对象的 属性列表 中,省略重复项,并按 顺序排列。 -
如果此
NamedNodeMap对象的 元素 位于 HTML 命名空间 中,且其 节点文档 是一个 HTML 文档,则 对于每个 name,来自 names:-
令 lowercaseName 为 name 的 ASCII 小写 形式。
-
如果 lowercaseName 不等于 name,则移除 name,从 names 中。
-
-
返回 names。
getNamedItem(qualifiedName)
方法步骤是返回在给定 qualifiedName 和元素的情况下,获取属性的结果。
getNamedItemNS(namespace, localName)
方法步骤是返回在给定
namespace、localName 和元素的情况下,获取属性的结果。
setNamedItem(attr) 和
setNamedItemNS(attr) 方法步骤是
返回在给定 attr 和
元素的情况下,设置属性的结果。
removeNamedItem(qualifiedName)
方法步骤如下:
-
如果 attr 为 null,则抛出一个“
NotFoundError”DOMException。 -
返回 attr。
removeNamedItemNS(namespace, localName)
方法步骤如下:
-
如果 attr 为 null,则抛出一个“
NotFoundError”DOMException。 -
返回 attr。
4.9.2.
接口 Attr
[Exposed =Window ]interface :Attr Node {readonly attribute DOMString ?namespaceURI ;readonly attribute DOMString ?prefix ;readonly attribute DOMString localName ;readonly attribute DOMString name ; [CEReactions ]attribute DOMString value ;readonly attribute Element ?ownerElement ;readonly attribute boolean specified ; // historical; always returns true };
Attr 节点简称为
属性。它们有时也称为
内容属性,以避免与 IDL 属性混淆。
属性具有 命名空间(null 或非空字符串)、 命名空间前缀(null 或非空字符串)、 本地名称(一个非空字符串)、 值(一个字符串),以及 元素(null 或一个 元素)。
如果在今天设计,它们就只会有名称和值了。☹
一个属性的
限定名称,如果其
本地名称对应的命名空间
前缀为 null,则为其本地名称;否则为其
命名空间前缀,后跟 ":",
再后跟其
本地名称。
用户代理可以将其存储在内部槽中以进行优化。
要 创建一个 属性,给定一个 文档 document、一个 字符串 localName,以及可选的字符串或 null namespace(默认为 null)、一个 字符串或 null prefix(默认为 null),以及一个字符串 value(默认为空 字符串):
一个
A 属性
是一个 属性,其
局部名称 为
A,且其
命名空间 和
命名空间前缀 均为
null。
此 namespaceURI 获取器的步骤是返回
this 的 命名空间。
此 prefix 获取器的步骤是返回 this 的
命名空间前缀。
此 localName 获取器的步骤是返回
this 的 局部名称。
要 设置一个 现有属性值,给定一个 属性 attribute 和 字符串 value,运行以下步骤:
-
令 element 为 attribute 的 元素。
-
令 verifiedValue 为调用以下算法的结果: 获取符合可信类型的属性 值,使用 attribute 的 局部名称、attribute 的 命名空间、element, 和 value。[TRUSTED-TYPES]
-
如果 attribute 的 元素 为 null,则将 attribute 的 值 设置为 verifiedValue 并返回。
-
更改 attribute 为 verifiedValue。
此 value
设置器的步骤是 设置现有属性值,使用 this
和给定的值。
此 ownerElement 获取器的步骤是返回
this 的 元素。
此 specified 获取器的步骤是返回 true。
4.10.
接口 CharacterData
[Exposed =Window ]interface :CharacterData Node {attribute [LegacyNullToEmptyString ]DOMString data ;readonly attribute unsigned long length ;DOMString substringData (unsigned long ,offset unsigned long );count undefined appendData (DOMString );data undefined insertData (unsigned long ,offset DOMString );data undefined deleteData (unsigned long ,offset unsigned long );count undefined replaceData (unsigned long ,offset unsigned long ,count DOMString ); };data
CharacterData
是一个抽象接口。你无法直接获取其实例。它
由Text、ProcessingInstruction
和Comment 节点使用。
每个继承自
CharacterData
接口的节点都有一个关联的可变
字符串,称为数据。
要替换数据,对于 一个节点 node, 使用整数 offset、整数 count、字符串 data 和一个可选的 布尔值 piAttributesAlreadyUpdated(默认为 false):
-
令 length 为 node 的长度。
-
如果 offset 大于 length,则抛出一个 "
IndexSizeError"DOMException。 -
如果 offset + count 大于 length,则将 count 设置为 length − offset。
-
为 node 将一个变更记录加入队列,类型为 "
characterData",并传入 null、null、node 的数据、« »、« »、null 和 null。 -
令 deleteOffset 为 offset + data 的 长度。
-
对于每个活动 范围,如果其起始节点为 node,且 起始偏移量大于 offset 但小于或等于 offset + count:将其起始偏移量 设置为 offset。
-
对于每个活动范围,如果其结束节点为 node,且 结束偏移量大于 offset,但 小于或等于 offset + count:将其结束偏移量设置为 offset。
-
对于每个活动范围,如果其起始节点为 node,且 起始偏移量大于 offset + count:将其 起始偏移量增加 data 的长度,再减去 count。
-
对于每个活动范围,如果其结束节点为 node,且 结束偏移量大于 offset + count:将其 结束偏移量增加 data 的长度,再减去 count。
-
如果 node 是一个
ProcessingInstruction节点,且 piAttributesAlreadyUpdated 为 false,则根据数据更新 属性,给定 node。
要 截取数据子串, 对于一个节点 node, 使用整数 offset 和整数 count:
4.11. 接口 Text
[Exposed =Window ]interface :Text CharacterData {constructor (optional DOMString = ""); [data NewObject ]Text splitText (unsigned long );offset readonly attribute DOMString wholeText ; };
text = new Text([data = ""])- 返回一个新的
Text节点,其 数据为 data。 text .splitText(offset)- 在给定的
offset 处拆分数据,
并将剩余部分作为
Text节点返回。 text .wholeText- 返回所有直接相邻的
Text节点 同胞节点的数据连接后的结果。
一个专属 Text 节点
是一个Text 节点,但不是
CDATASection
节点。
一个节点 node 的连续的 Text 节点
包括
node、node 的前一个同胞节点(如果它是Text 节点),及其
连续的
Text 节点,以及 node 的后一个同胞节点
(如果它是Text 节点),及其连续的
Text 节点,并排除
所有重复项。
一个节点 node 的连续的专属 Text 节点
包括 node、node 的前一个同胞节点
(如果它是专属
Text 节点),及其
连续的专属 Text 节点,以及
node 的
后一个
同胞节点(如果它是专属 Text 节点),及其
连续的专属 Text 节点,
并排除所有重复项。
要 创建文本 节点,给定一个 文档 document 和一个 字符串 data:
要 拆分 一个 Text
节点 node,使用
整数 offset:
-
令 length 为 node 的 长度。
-
如果 offset 大于 length,则 抛出 一个 "
IndexSizeError"DOMException。 -
令 count 为 length − offset。
-
令 newData 为 截取数据子串 的结果,针对 node 使用 offset 和 count。
-
令 parent 为 node 的 父节点。
-
如果 parent 非 null:
-
对于每个 活动范围,其 起始 节点 为 node 且 起始偏移量 大于 offset,将其 起始节点 设置为 newNode,并 将其 起始偏移量 减去 offset。
-
对于每个 活动范围,其 结束节点 为 node 且 结束偏移量 大于 offset,将其 结束节点 设置为 newNode,并将其 结束 偏移量 减去 offset。
-
对于每个 活动范围,其 起始 节点 为 parent 且 起始偏移量 等于 索引(属于 node)加 1, 将其 起始偏移量 增加 1。
-
对于每个 活动范围,其 结束节点 为 parent 且 结束偏移量 等于 索引(属于 node)加 1, 将其 结束偏移量 增加 1。
-
替换 数据,针对 node 使用 offset、count 和 空字符串。
-
返回 newNode。
此 wholeText 获取器的步骤是返回
拼接 以下 数据 的结果,这些数据来自
连续的
Text 节点,属于 this,按 树序。
4.12. 接口 CDATASection
[Exposed =Window ]interface :CDATASection Text { };
要创建一个 CDATA 节节点,给定一个文档 document 和一个字符串 data:
-
令 node 为创建节点的结果,该节点实现
CDATASection, 给定 document。 -
将 node 的数据设置为 data。
-
返回 node。
4.13.
接口 ProcessingInstruction
[Exposed =Window ]interface :ProcessingInstruction CharacterData {constructor (DOMString ,target optional DOMString = "");data readonly attribute DOMString target ;boolean hasAttributes ();sequence <DOMString >getAttributeNames ();DOMString ?getAttribute (DOMString );name undefined setAttribute (DOMString ,name DOMString );value undefined removeAttribute (DOMString );name boolean toggleAttribute (DOMString ,name optional boolean );force boolean hasAttribute (DOMString ); };name
pi = new ProcessingInstruction(target [, data = ""])- 返回一个新的
ProcessingInstruction节点,其 目标为 target,且 数据为 data。 pi .target- 返回目标。
pi . hasAttributes()-
如果 pi 具有属性,则返回 true;否则返回 false。
pi . getAttributeNames()-
返回 pi 的所有属性名称。不能包含重复项。
pi . getAttribute(name)-
返回 pi 中名称为 name 的属性值;如果 不存在这样的属性,则返回 null。
pi . setAttribute(name, value)-
将 pi 中名称为 name 的属性设置为 value。
pi . removeAttribute(name)-
移除 pi 中名称为 name 的属性。
pi . toggleAttribute(name [, force])-
如果未提供 force,则“切换” name,即如果它 存在则移除它,如果不存在则添加它。如果 force 为 true,则添加 name。如果 force 为 false,则移除 name。
如果 name 现在存在,则返回 true;否则返回 false。
pi . hasAttribute(name)-
如果 pi 具有名称为 name 的属性,则返回 true;否则返回 false。
ProcessingInstruction
节点具有一个关联的
目标。
ProcessingInstruction
节点具有一个关联的
属性映射,它是一个
映射,
初始为空。
要创建一个处理指令节点,给定一个文档 document、字符串 target 和字符串 data:
-
令 pi 为创建节点的结果,该节点实现
ProcessingInstruction, 给定 document。 -
使用 target 和 data 初始化 pi。
-
返回 pi。
要初始化一个ProcessingInstruction
节点 pi,使用
target 和 data:
-
如果 target 不匹配
Name产生式,则 抛出一个 "InvalidCharacterError"DOMException。 -
如果 data 包含字符串 "
?>",则抛出一个 "InvalidCharacterError"DOMException。 -
将 pi 的目标设置为 target。
-
将 pi 的数据设置为 data。
-
给定 pi,根据数据更新属性。
要根据数据
更新属性,给定一个ProcessingInstruction
节点
pi:
要根据属性
更新数据,给定一个ProcessingInstruction
节点
pi:
-
令 data 为空字符串。
-
对于 pi 的 属性映射中的每个 name → value:
-
如果 data 不为空字符串,则将 U+0020 SPACE 追加到 data。
-
将 name 追加到 data。
-
将 U+003D (=) 追加到 data。
-
将 U+0022 (") 追加到 data。
-
将 value 中的所有 U+0026 (&) 替换为 "
&"。 -
将 value 中的所有 U+003C (<) 替换为 "
<"。 -
将 value 中的所有 U+003E (>) 替换为 "
>"。 -
将 value 中的所有 U+0022 (") 替换为 "
""。 -
将 value 追加到 data。
-
将 U+0022 (") 追加到 data。
-
要获取处理指令属性,给定一个
ProcessingInstruction
节点 pi 和一个
字符串 name:返回 pi 的
属性映射[name],默认值
为 null。
此
new ProcessingInstruction(target, data)
构造函数的步骤如下:
此
setAttribute(name, value)
方法的步骤如下:
-
如果 name 不是一个 有效的属性局部名称,则 抛出 一个 "
InvalidCharacterError"DOMException。
此
toggleAttribute(name, force)
方法的步骤如下:
4.14.
接口 Comment
[Exposed =Window ]interface :Comment CharacterData {constructor (optional DOMString = ""); };data
comment = new Comment([data = ""])- 返回一个新的
Comment节点,其 数据为 data。
要 创建注释 节点,给定一个 文档 document 和 一个字符串 data:
5. 范围
5.1. “DOM 范围”简介
StaticRange
和 Range 对象(范围)表示
节点树中的一段
内容序列。每个范围都有一个起点和一个终点,它们
是边界点。一个边界点是一个由
元组组成的
节点和一个偏移。换句话说,
一个
范围表示节点
树中两个
边界点之间的一段
内容。
范围经常用于 编辑中的内容选择和复制。
-
Element:p
在上面的节点树
中,可以使用一个
范围来表示
序列
“syndata is awes”。假设将 p 赋值为
p 元素,
并将
em 赋值为 em
元素,可以
按如下方式完成:
var range = new Range(),
firstText = p. childNodes[ 1 ],
secondText = em. firstChild
range. setStart( firstText, 9 ) // 不要忘记前导空格
range. setEnd( secondText, 4 )
// range 现在转换为字符串后就是前述引文
上面节点树中的 src 和 alt 等
属性无法由范围表示。范围仅适用于
节点。
Range 对象与
StaticRange
对象不同,会受到
节点树突变的影响。因此
它们也称为实时范围。此类突变不会
使它们失效,并会尝试确保它仍表示相同的内容片段。
必然地,当例如其所表示内容的一部分发生突变时,作为
节点树突变的一部分,实时
范围本身也可能被修改。
有关详细信息,请参阅插入和移除算法、
normalize()
方法,以及替换
数据和拆分
算法。
为响应节点
树突变而更新实时范围
可能成本高昂。每当
节点树发生更改时,所有
受影响的 Range
对象都需要更新。即使应用程序
对某些实时范围不感兴趣,在发生突变时,它仍须承担使它们
保持最新状态
的成本。
一个 StaticRange
对象是一个轻量级范围,
在
节点树发生突变时不会更新。因此它
不会产生与
实时范围相同的维护成本。
5.2. 边界点
一个 边界点是一个元组, 由一个 节点(一个节点)和一个 偏移量(一个非负整数)组成。
一个正确的边界点的偏移量将 位于 0 与该边界点的节点的 长度 之间,包括两端。
一个 边界点 (nodeA、offsetA)相对于另一个边界点 (nodeB、offsetB)的 位置是 之前、 相等或 之后,由以下步骤返回:
5.3. 接口 AbstractRange
[Exposed =Window ]interface {AbstractRange readonly attribute Node startContainer ;readonly attribute unsigned long startOffset ;readonly attribute Node endContainer ;readonly attribute unsigned long endOffset ;readonly attribute boolean collapsed ; };
实现 AbstractRange
接口的对象被称为 范围。
为方便起见,一个范围的起始节点是其起始点的节点,其起始偏移量是其起始点的偏移量,其结束节点是其结束点的节点,其结束偏移量是其结束点的偏移量。
node = range . startContainer- 返回 range 的起始节点。
offset = range . startOffset- 返回 range 的起始偏移量。
node = range . endContainer- 返回 range 的结束节点。
offset = range . endOffset- 返回 range 的结束偏移量。
collapsed = range . collapsed- 如果 range 是折叠的,则返回 true;否则返回 false。
5.4. 接口 StaticRange
dictionary {StaticRangeInit required Node ;startContainer required unsigned long ;startOffset required Node ;endContainer required unsigned long ; }; [endOffset Exposed =Window ]interface :StaticRange AbstractRange {constructor (StaticRangeInit ); };init
该
new StaticRange(init)
构造函数的步骤如下:
-
如果 init["
startContainer"] 或 init["endContainer"] 是一个DocumentType或Attr节点,则抛出一个 "InvalidNodeTypeError"DOMException。 -
将this 的起点设置为 (init["
startContainer"], init["startOffset"]), 并将终点设置为 (init["endContainer"], init["endOffset"])。
如果以下所有条件均为 true,则一个 StaticRange
是有效的:
5.5. 接口 Range
[Exposed =Window ]interface :Range AbstractRange {constructor ();readonly attribute Node commonAncestorContainer ;undefined setStart (Node ,node unsigned long );offset undefined setEnd (Node ,node unsigned long );offset undefined setStartBefore (Node );node undefined setStartAfter (Node );node undefined setEndBefore (Node );node undefined setEndAfter (Node );node undefined collapse (optional boolean =toStart false );undefined selectNode (Node );node undefined selectNodeContents (Node );node const unsigned short = 0;START_TO_START const unsigned short = 1;START_TO_END const unsigned short = 2;END_TO_END const unsigned short = 3;END_TO_START short compareBoundaryPoints (unsigned short ,how Range ); [sourceRange CEReactions ]undefined deleteContents (); [CEReactions ,NewObject ]DocumentFragment extractContents (); [CEReactions ,NewObject ]DocumentFragment cloneContents (); [CEReactions ]undefined insertNode (Node ); [node CEReactions ]undefined surroundContents (Node ); [newParent NewObject ]Range cloneRange ();undefined detach ();boolean isPointInRange (Node ,node unsigned long );offset short comparePoint (Node ,node unsigned long );offset boolean intersectsNode (Node );node stringifier ; };
实现Range 接口的对象
称为
活动范围。
修改树的算法(特别是插入、 移除、移动、替换数据和拆分 算法)会修改与该树关联的活动 范围。
一个节点 node 被包含 在一个活动范围 range 中,如果 node 的根是 range 的根,且 (node, 0) 位于 range 的起点之后,并且 (node, node 的长度) 位于 range 的终点之前。
一个节点 被部分包含在一个活动范围中, 如果它是该活动范围的起始节点的包含自身的祖先, 但不是其结束 节点的包含自身的祖先,或者情况相反。
以下事实有助于理解这些定义:
-
通常认为位于活动范围内的内容包括所有 被包含的节点,以及 可能还包括 起始节点和结束节点的部分内容,如果它们 是
CharacterData节点。 -
第一个被包含的节点(如果 存在) 一定位于起始节点之后,而最后一个被包含的 节点一定 等于或位于结束节点的最后一个 后代之前。
-
commonAncestorContainer属性的值既不 被包含,也不被部分 包含。 -
如果起始节点是 结束 节点的祖先,则共同的包含自身的祖先就是 起始节点。其子节点中恰好有一个 被部分 包含,并且一个子节点 被包含,当且仅当 它先于该 被部分 包含的子节点。如果 结束 节点是起始节点的祖先,则情况 相反。
-
如果起始节点不是 结束 节点的包含自身的祖先, 反之亦然,则共同的包含自身的祖先将 与两者都不同。其子节点中恰好有两个 被部分 包含,且一个子节点被包含,当且 仅当它位于这两个子节点之间。
给定一个节点 node,活动 范围移除前步骤如下:
range = new Range()- 返回一个新的活动 范围。
此 new Range() 构造函数
的步骤是
将 this 的 起点 和 终点 设置为
(当前全局对象 的 关联的 Document, 0)。
- container = range .
commonAncestorContainer - 返回这样一个 节点,它距离 文档 最远,并且是一个共同的 祖先, 对应于 range 的 起始节点 和 结束 节点。
要 获取共同 祖先,对于一个 活动范围 range:
要 设置起点或终点, 将 range 的相应边界设为 边界点 (node, offset):
-
如果 node 是一个 文档类型,则 抛出 一个 "
InvalidNodeTypeError"DOMException。 -
如果 offset 大于 node 的 长度,则 抛出 一个 "
IndexSizeError"DOMException。 -
令 boundaryPoint 为 边界点 (node, offset)。
此 setStartBefore(node) 方法的步骤如下:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出 一个 "
InvalidNodeTypeError"DOMException。
此 setStartAfter(node) 方法的步骤如下:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出 一个 "
InvalidNodeTypeError"DOMException。
此 setEndBefore(node) 方法的步骤如下:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出 一个 "
InvalidNodeTypeError"DOMException。
此 setEndAfter(node) 方法的步骤如下:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出 一个 "
InvalidNodeTypeError"DOMException。
要 选择 一个 节点 node, 在一个 范围 range 内:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出 一个 "
InvalidNodeTypeError"DOMException。 -
令 index 为 node 的 索引。
此 selectNodeContents(node) 方法
的步骤
如下:
-
如果 node 是一个 文档类型,则 抛出 一个 "
InvalidNodeTypeError"DOMException。 -
令 length 为以下节点的 长度:node。
此
compareBoundaryPoints(how, sourceRange)
方法的步骤如下:
-
如果 how 不是以下值之一
则 抛出 一个 "
NotSupportedError"DOMException。 -
如果 this 的 根 不是 sourceRange 的 根, 则 抛出 一个 "
WrongDocumentError"DOMException。 -
令 thisPoint 和 sourcePoint 为 null。
-
根据 how 分情况处理:
START_TO_START:-
将 thisPoint 设置为 this 的 起点,并将 sourcePoint 设置为 sourceRange 的 起点。
START_TO_END:-
将 thisPoint 设置为 this 的 终点,并将 sourcePoint 设置为 sourceRange 的 起点。
END_TO_END:-
将 thisPoint 设置为 this 的 终点,并将 sourcePoint 设置为 sourceRange 的 终点。
END_TO_START:-
将 thisPoint 设置为 this 的 起点,并将 sourcePoint 设置为 sourceRange 的 终点。
-
根据以下 位置 分情况处理:thisPoint 相对于 sourcePoint 的位置:
此 deleteContents() 方法的步骤如下:
-
令 originalStartNode、originalStartOffset、 originalEndNode 和 originalEndOffset 分别为 this 的 起始节点、起始 偏移量、结束节点 和 结束偏移量。
-
如果 originalStartNode 是 originalEndNode,且它是一个
CharacterData节点:-
替换数据,对 originalStartNode 使用 originalStartOffset、 originalEndOffset − originalStartOffset 和空字符串。
-
返回。
-
-
令 nodesToRemove 为所有以下 节点 的列表:这些节点 被包含 在 this 中,按 树序 排列,并省略任何满足以下条件的 节点:其 父节点 也 被包含 在 this 中。
-
令 newNode 和 newOffset 为 null。
-
如果 originalStartNode 是以下节点的 包含自身的祖先: originalEndNode,则将 newNode 设置为 originalStartNode,并将 newOffset 设置为 originalStartOffset。
-
否则:
-
令 referenceNode 为 originalStartNode。
-
只要 referenceNode 的 父节点 非 null,且不是以下节点的 包含自身的祖先: originalEndNode,就将 referenceNode 设置为 其 父节点。
-
将 newNode 设置为 referenceNode 的 父节点,并将 newOffset 设置为 referenceNode 的 索引 + 1。
如果 referenceNode 的 父节点 为 null, 那么它就会是以下范围的 根:this。这样一来, 它就会是以下节点的 包含自身的祖先: originalEndNode,因而不可能执行到 此处。
-
-
如果 originalStartNode 是一个
CharacterData节点,则 替换 数据,对 originalStartNode 使用 originalStartOffset、 originalStartNode 的 长度 − originalStartOffset 和 空字符串。 -
如果 originalEndNode 是一个
CharacterData节点,则 替换 数据,对 originalEndNode 使用 0、originalEndOffset 和 空字符串。
要 提取 一个 活动范围 range:
-
如果 range 是 折叠的,则返回 fragment。
-
令 originalStartNode、originalStartOffset、 originalEndNode 和 originalEndOffset 分别为 range 的 起始节点、起始 偏移量、结束节点 和 结束偏移量。
-
如果 originalStartNode 是 originalEndNode,且它是一个
CharacterData节点: -
令 commonAncestor 为以下操作的结果:获取共同 祖先,对应于 range。
-
令 firstPartiallyContainedChild 为 null。
- 如果 originalStartNode 不是以下节点的 包含自身的 祖先: originalEndNode,则将 firstPartiallyContainedChild 设置为第一个满足以下条件的 子节点:它属于 commonAncestor,并且 部分 被包含 在 range 中。
-
令 lastPartiallyContainedChild 为 null。
-
如果 originalEndNode 不是以下节点的 包含自身的祖先: originalStartNode,则将 lastPartiallyContainedChild 设置为最后一个满足以下条件的 子节点: 它属于 commonAncestor,并且 部分 被包含 在 range 中。
这些变量赋值实际上始终是有意义的。例如, 如果 originalStartNode 不是以下节点的 包含自身的祖先: originalEndNode,那么 originalStartNode 本身就 部分 被包含 在 range 中,其所有 祖先 也都是如此,直到某个 子节点,它属于 commonAncestor。 commonAncestor 不可能是 originalStartNode,因为它必须是以下节点的 包含自身的祖先: originalEndNode。另一种情况与此类似。另外, 请注意,这两个 子节点 如果都已定义,就绝不会相同。
-
令 containedChildren 为所有以下 子节点 的列表:它们属于 commonAncestor,并且 被包含 在 range 中,按 树 序 排列。
-
如果 containedChildren 的任何成员是一个 文档类型,则 抛出 一个 "
HierarchyRequestError"DOMException。我们不必担心第一个或最后一个部分 被包含的节点,因为 文档类型 永远不可能 部分被包含。它不能是范围的边界点,也 不能是任何节点的祖先。
-
令 newNode 和 newOffset 为 null。
-
如果 originalStartNode 是以下节点的 包含自身的祖先: originalEndNode,则将 newNode 设置为 originalStartNode,并将 newOffset 设置为 originalStartOffset。
-
否则:
-
令 referenceNode 为 originalStartNode。
-
只要 referenceNode 的 父节点 非 null,且不是以下节点的 包含自身的祖先: originalEndNode,就将 referenceNode 设置为 其 父节点。
-
将 newNode 设置为以下节点的 父节点:referenceNode,并将 newOffset 设置为 referenceNode 的 索引 + 1。
如果 referenceNode 的 父节点 为 null, 那么它就会是以下范围的 根:range。这样一来,它就会是 以下节点的 包含自身的祖先: originalEndNode,因而不可能执行到 此处。
-
-
如果 firstPartiallyContainedChild 是一个
CharacterData节点:在这种情况下,firstPartiallyContainedChild 就是 originalStartNode。
-
否则,如果 firstPartiallyContainedChild 非 null:
-
对于每个 contained child,来自 containedChildren:追加 contained child 到 fragment。
-
如果 lastPartiallyContainedChild 是一个
CharacterData节点:在这种情况下,lastPartiallyContainedChild 就是 originalEndNode。
-
否则,如果 lastPartiallyContainedChild 非 null:
-
返回 fragment。
要 克隆内容, 对于一个 活动范围 range:
-
如果 range 是 折叠的,则返回 fragment。
-
令 originalStartNode、originalStartOffset、 originalEndNode 和 originalEndOffset 分别为 range 的 起始节点、起始 偏移量、结束节点 和 结束偏移量。
-
如果 originalStartNode 是 originalEndNode,且它是一个
CharacterData节点: -
令 commonAncestor 为以下操作的结果:获取共同 祖先,对应于 range。
-
令 firstPartiallyContainedChild 为 null。
-
如果 originalStartNode 不是以下节点的 包含自身的祖先: originalEndNode,则将 firstPartiallyContainedChild 设置为第一个满足以下条件的 子节点: 它属于 commonAncestor,并且 部分 被包含 在 range 中。
-
令 lastPartiallyContainedChild 为 null。
-
如果 originalEndNode 不是以下节点的 包含自身的祖先: originalStartNode,则将 lastPartiallyContainedChild 设置为最后一个满足以下条件的 子节点: 它属于 commonAncestor,并且 部分 被包含 在 range 中。
这些变量赋值实际上始终是有意义的。例如, 如果 originalStartNode 不是以下节点的 包含自身的祖先: originalEndNode,那么 originalStartNode 本身就 部分 被包含 在 range 中,其所有 祖先 也都是如此,直到某个 子节点,它属于 commonAncestor。 commonAncestor 不可能是 originalStartNode,因为它必须是以下节点的 包含自身的祖先: originalEndNode。另一种情况与此类似。另外, 请注意,这两个 子节点 如果都已定义,就绝不会相同。
-
令 containedChildren 为所有以下 子节点 的列表:它们属于 commonAncestor,并且 被包含 在 range 中,按 树 序 排列。
-
如果 containedChildren 的任何成员是一个 文档类型,则 抛出 一个 "
HierarchyRequestError"DOMException。我们不必担心第一个或最后一个部分 被包含的节点,因为 文档类型 永远不可能 部分被包含。它不能是范围的边界点,也 不能是任何节点的祖先。
-
如果 firstPartiallyContainedChild 是一个
CharacterData节点:在这种情况下,firstPartiallyContainedChild 就是 originalStartNode。
-
否则,如果 firstPartiallyContainedChild 非 null:
-
对于每个 contained child,来自 containedChildren:
-
如果 lastPartiallyContainedChild 是一个
CharacterData节点:在这种情况下,lastPartiallyContainedChild 就是 originalEndNode。
-
否则,如果 lastPartiallyContainedChild 非 null:
-
返回 fragment。
要 插入 一个 节点 node 到一个 活动范围 range 中:
-
如果 range 的 起始节点 是一个
ProcessingInstruction或Comment节点,是一个Text节点 且其 父节点 为 null,或者就是 node,则 抛出 一个 "HierarchyRequestError"DOMException。 -
令 referenceNode 为 null。
-
否则,将 referenceNode 设置为以下 子节点:它属于 range 的 起始节点,且其 索引 为 range 的 起始偏移量,如果存在这样的 子节点; 否则设置为 null。
-
令 parent 为 range 的 起始节点,如果 referenceNode 为 null;否则为 referenceNode 的 父节点。
-
确保预插入有效性, 给定 node、parent、 referenceNode 和 « »。
-
如果 range 的 起始节点 是一个
Text节点,则将 referenceNode 设置为以下操作的结果:拆分 该节点,使用的偏移量为 range 的 起始偏移量。 -
如果 node 是 referenceNode,则将 referenceNode 设置为其 下一个兄弟节点。
-
令 newOffset 为 parent 的 长度,如果 referenceNode 为 null;否则为 referenceNode 的 索引。
-
将 newOffset 增加 node 的 长度,如果 node 是一个
DocumentFragment节点;否则增加 1。 -
预插入 node 到 parent 中, 位于 referenceNode 之前。
此 surroundContents(newParent) 方法
的步骤
如下:
-
如果一个非
Text节点 部分被包含 在 this 中,则 抛出 一个 "InvalidStateError"DOMException。 -
如果 newParent 是一个
Document、DocumentType或DocumentFragment节点,则 抛出 一个 "InvalidNodeTypeError"DOMException。由于历史原因,
CharacterData节点 不会 在此处检查,而最终会在后续操作中作为副作用抛出异常。 -
追加 fragment 到 newParent。
此 detach() 方法的步骤是不执行任何操作。
其功能(禁用一个 Range 对象)
已被移除,但该方法本身
为了兼容性而保留。
- position = range .
comparePoint(node, offset) - 如果该点位于范围之前,则返回 −1;如果该点位于 范围内,则返回 0;如果该点位于范围之后,则返回 1。
- intersects = range .
intersectsNode(node) - 返回 range 是否与 node 相交。
此 isPointInRange(node, offset)
方法的步骤如下:
-
如果 node 是一个 文档类型,则 抛出 一个 "
InvalidNodeTypeError"DOMException。 -
如果 offset 大于 node 的 长度,则 抛出 一个 "
IndexSizeError"DOMException。 -
返回 true。
此 comparePoint(node, offset)
方法的步骤如下:
-
如果 node 的 根 不是 this 的 根, 则 抛出 一个 "
WrongDocumentError"DOMException。 -
如果 node 是一个 文档类型,则 抛出 一个 "
InvalidNodeTypeError"DOMException。 -
如果 offset 大于 node 的 长度,则 抛出 一个 "
IndexSizeError"DOMException。 -
返回 0。
此 intersectsNode(node) 方法的步骤如下:
此 字符串化行为 必须运行 以下步骤:
-
令 string 为空字符串。
-
如果 this 的 起始节点 是 this 的 结束节点,并且 它是一个
Text节点,则返回 该Text节点 的 数据 的子串, 从 this 的 起始偏移量 开始,并 在 this 的 结束偏移量 结束。 -
如果 this 的 起始节点 是一个
Text节点,则将 该 节点 的 数据 中从 this 的 起始偏移量 到末尾的子串追加到 string。 -
将以下 拼接 结果追加:这些 数据 来自所有
Text节点,这些节点 被包含 在 this 中,按 树 序 拼接,追加到 string。 -
如果 this 的 结束节点 是一个
Text节点,则 将该 节点 的 数据 中从开头到 this 的 结束偏移量 的子串追加到 string。 -
返回 string。
这些 createContextualFragment()、
getClientRects()
和 getBoundingClientRect()
方法在其他规范中定义。
[DOM-Parsing]
[CSSOM-VIEW]
6. 遍历
NodeIterator
和TreeWalker
对象可用于筛选和遍历节点
树。
每个NodeIterator
和TreeWalker
对象都有一个关联的布尔值
是否处于活动状态,用于避免递归调用。其
初始值为 false。
每个NodeIterator
和TreeWalker
对象还具有一个关联的
根(一个节点)、一个
whatToShow(一个位掩码)和一个
过滤器(一个回调)。
要筛选一个节点 node,
使用
一个NodeIterator
或TreeWalker
对象 traverser:
-
如果 traverser 的是否处于活动状态为 true,则抛出一个 "
InvalidStateError"DOMException。 -
令 n 为 node 的
nodeType属性值 − 1。 -
如果第 nth 位(其中 0 是最低有效位)在 traverser 的whatToShow 中未被设置,则返回
FILTER_SKIP。 -
如果 traverser 的过滤器为 null,则返回
FILTER_ACCEPT。 -
将 traverser 的是否处于活动状态设置为 true。
-
令 result 为调用用户对象的操作的返回值,传入 traverser 的过滤器、"
acceptNode" 和 « node »。如果此调用抛出异常,则将 traverser 的 是否处于活动状态设置为 false,并重新抛出该异常。 -
将 traverser 的是否处于活动状态设置为 false。
-
返回 result。
6.1. 接口 NodeIterator
[Exposed =Window ]interface { [NodeIterator SameObject ]readonly attribute Node root ;readonly attribute Node referenceNode ;readonly attribute boolean pointerBeforeReferenceNode ;readonly attribute unsigned long whatToShow ;readonly attribute NodeFilter ?filter ;Node ?nextNode ();Node ?previousNode ();undefined detach (); };
NodeIterator
对象可以使用
createNodeIterator()
方法在Document
对象上创建。
每个NodeIterator
对象都有一个关联的
迭代器集合,它是一个
集合,以
NodeIterator
对象的根为根,其
过滤器匹配任何节点。
一个节点指针是一个元组, 由一个 节点(一个节点)和一个 指针位于前方(一个布尔值)组成。
每个NodeIterator
对象还具有一个关联的引用(一个
节点指针)和候选引用(null 或一个
节点指针,初始值为
null)。
如前所述,NodeIterator
对象还具有一个关联的
是否
处于活动状态、根、whatToShow 和
过滤器。
给定一个NodeIterator
对象 nodeIterator 和一个节点
toBeRemovedNode,NodeIterator 移除前步骤
如下:
要调整节点指针,给定一个节点指针
nodePointer、一个NodeIterator
对象 nodeIterator 和一个节点
toBeRemovedNode,执行以下步骤。这些步骤返回一个节点指针。
此 whatToShow 获取器的步骤是返回
this 的 whatToShow。
要 遍历,给定一个
NodeIterator
对象 iterator 和值为 "next" 或 "previous" 的
type:
-
令 result 为 null。
-
当 true 时:
-
如果 type 为 "
next": -
否则:
-
令 filterResult 为以下操作的结果:过滤 node,在 iterator 内。如果此操作抛出异常,则将 iterator 的 候选引用 设置为 null,并 重新抛出该异常。
-
如果 filterResult 为
FILTER_ACCEPT:
-
-
将 iterator 的 候选引用 设置为 null。
-
返回 result。
此 detach() 方法的步骤是不执行任何操作。
其功能(禁用一个 NodeIterator
对象)已被移除,但该方法
本身为了兼容性而保留。
6.2.
接口 TreeWalker
[Exposed =Window ]interface { [TreeWalker SameObject ]readonly attribute Node root ;readonly attribute unsigned long whatToShow ;readonly attribute NodeFilter ?filter ;attribute Node currentNode ;Node ?parentNode ();Node ?firstChild ();Node ?lastChild ();Node ?previousSibling ();Node ?nextSibling ();Node ?previousNode ();Node ?nextNode (); };
TreeWalker
对象可以使用createTreeWalker()
方法在Document
对象上创建。
每个TreeWalker
对象都有一个关联的当前节点(一个
节点)。
如前所述,TreeWalker
对象还具有一个关联的
根、whatToShow 和过滤器。
此 whatToShow 获取器的步骤是返回
this 的 whatToShow。
此 currentNode
设置器的步骤是将 this 的
当前节点 设置为
给定值。
此 parentNode() 方法的步骤如下:
要 遍历子节点,给定一个
TreeWalker
对象 walker 和值为 "first" 或 "last" 的
type:
-
令 node 为 walker 的 当前节点。
-
将 node 设置为 node 的 第一个子节点,如果 type 为 "
first";否则设置为 node 的 最后一个子节点。 -
只要 node 非 null:
-
令 result 为以下操作的结果:过滤 node,在 walker 内。
-
如果 result 为
FILTER_ACCEPT, 则将 walker 的 当前节点 设置为 node,并返回 node。 -
如果 result 为
FILTER_SKIP: -
只要 node 非 null:
-
-
返回 null。
要 遍历
兄弟节点,给定一个 TreeWalker
对象 walker 和值为 "next" 或 "previous" 的 type:
-
令 node 为 walker 的 当前节点。
-
如果 node 是 根,则返回 null。
-
当 true 时:
-
令 sibling 为 node 的 下一个 兄弟节点,如果 type 为 "
next";否则为 node 的 上一个兄弟节点。 -
只要 sibling 非 null:
-
将 node 设置为 sibling。
-
令 result 为以下操作的结果:过滤 node,在 walker 内。
-
如果 result 为
FILTER_ACCEPT, 则将 walker 的 当前节点 设置为 node,并返回 node。 -
将 sibling 设置为 node 的 第一个子节点,如果 type 为 "
next";否则设置为 node 的 最后一个子节点。 -
如果 result 为
FILTER_REJECT或 sibling 为 null,则 将 sibling 设置为 node 的 下一个兄弟节点,如果 type 为 "next";否则设置为 node 的 上一个兄弟节点。
-
-
将 node 设置为 node 的 父节点。
-
如果 node 为 null 或 walker 的 根,则 返回 null。
-
如果以下操作的返回值:过滤 node,在 walker 内,为
FILTER_ACCEPT, 则返回 null。
-
此 previousNode() 方法的步骤如下:
此 nextNode() 方法的步骤如下:
-
令 result 为
FILTER_ACCEPT。 -
当 true 时:
-
只要 result 不是
FILTER_REJECT且 node 有一个 子节点: -
令 sibling 为 null。
-
令 temporary 为 node。
-
只要 temporary 非 null:
-
如果 sibling 为 null,则返回 null。
-
将 node 设置为 sibling。
-
如果 result 为
FILTER_ACCEPT, 则将 this 的 当前节点 设置为 node,并返回 node。
-
6.3.
接口 NodeFilter
[Exposed =Window ]callback interface { // Constants for acceptNode()NodeFilter const unsigned short FILTER_ACCEPT = 1;const unsigned short FILTER_REJECT = 2;const unsigned short FILTER_SKIP = 3; // Constants for whatToShowconst unsigned long SHOW_ALL = 0xFFFFFFFF;const unsigned long SHOW_ELEMENT = 0x1;const unsigned long SHOW_ATTRIBUTE = 0x2;const unsigned long SHOW_TEXT = 0x4;const unsigned long SHOW_CDATA_SECTION = 0x8;const unsigned long = 0x10; // legacySHOW_ENTITY_REFERENCE const unsigned long = 0x20; // legacySHOW_ENTITY const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40;const unsigned long SHOW_COMMENT = 0x80;const unsigned long SHOW_DOCUMENT = 0x100;const unsigned long SHOW_DOCUMENT_TYPE = 0x200;const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400;const unsigned long = 0x800; // legacySHOW_NOTATION unsigned short (acceptNode Node ); };node
NodeFilter
对象可以用作 filter
用于 NodeIterator
和 TreeWalker
对象,
并且为它们的 whatToShow 位掩码提供常量。
NodeFilter
对象通常实现为 JavaScript 函数。
这些常量可用作 过滤器 的返回值:
FILTER_ACCEPT(1);FILTER_REJECT(2);FILTER_SKIP(3)。
这些常量可用于 whatToShow:
SHOW_ALL(4294967295, 十六进制为 FFFFFFFF);SHOW_ELEMENT(1);SHOW_ATTRIBUTE(2);SHOW_TEXT(4);SHOW_CDATA_SECTION(8);SHOW_PROCESSING_INSTRUCTION(64, 十六进制为 40);SHOW_COMMENT(128, 十六进制为 80);SHOW_DOCUMENT(256, 十六进制为 100);SHOW_DOCUMENT_TYPE(512,十六进制为 200);SHOW_DOCUMENT_FRAGMENT(1024,十六进制为 400)。
7. 集合
是的,DOMTokenList
这个名称确实是遗留问题的不幸产物。
7.1.
接口 DOMTokenList
[Exposed =Window ]interface {DOMTokenList readonly attribute unsigned long length ;getter DOMString ?item (unsigned long );index boolean contains (DOMString ); [token CEReactions ]undefined add (DOMString ...); [tokens CEReactions ]undefined remove (DOMString ...); [tokens CEReactions ]boolean toggle (DOMString ,token optional boolean ); [force CEReactions ]boolean replace (DOMString ,token DOMString );newToken boolean supports (DOMString ); [token CEReactions ]stringifier attribute DOMString value ;iterable <DOMString >; };
一个DOMTokenList
对象具有一个关联的
令牌集合(一个集合),其
初始为空。
一个DOMTokenList
对象还具有一个关联的元素
(一个元素)和一个属性名称(一个属性的
本地名称)。
规范可以为DOMTokenList
的
元素和属性名称定义
受支持的令牌。
一个DOMTokenList
对象 set 针对给定
token 的
验证步骤如下:
一个DOMTokenList
对象 set 的
更新步骤如下:
一个DOMTokenList
对象 set 的
序列化步骤是返回
给定 set 的元素和
set 的属性名称,运行获取属性值的结果。
一个DOMTokenList
对象 set 具有针对
set 的元素的以下属性变更步骤:
当一个DOMTokenList
对象 set 被创建时:
tokenlist .length-
返回令牌的数量。
tokenlist .item(index)tokenlist[index]-
返回索引为 index 的令牌。
tokenlist .contains(token)-
如果 token 存在,则返回 true;否则返回 false。
tokenlist . add(tokens…)-
添加传入的所有参数,但不重复添加已存在的参数。
如果其中一个参数是空 字符串,则抛出一个 "
SyntaxError"DOMException。如果其中一个参数 包含任何ASCII 空白字符,则抛出一个 "
InvalidCharacterError"DOMException。 tokenlist . remove(tokens…)-
如果传入的参数存在,则将其移除。
如果其中一个参数是空 字符串,则抛出一个 "
SyntaxError"DOMException。如果其中一个参数 包含任何ASCII 空白字符,则抛出一个 "
InvalidCharacterError"DOMException。 tokenlist . toggle(token [, force])-
如果未提供 force,则“切换” token,即如果它存在就移除, 如果不存在就添加。如果 force 为 true,则添加 token (相当于
add())。 如果 force 为 false,则移除 token(相当于remove())。如果 token 现在存在,则返回 true;否则返回 false。
如果 token 为空,则抛出一个 "
SyntaxError"DOMException。如果 token 包含 任何空格,则抛出一个 "
InvalidCharacterError"DOMException。 tokenlist . replace(token, newToken)-
将 token 替换为 newToken。
如果 token 已被替换为 newToken,则返回 true;否则返回 false。
如果其中一个参数是空 字符串,则抛出一个 "
SyntaxError"DOMException。如果其中一个参数 包含任何ASCII 空白字符,则抛出一个 "
InvalidCharacterError"DOMException。 tokenlist . supports(token)-
如果 token 位于关联属性的受支持令牌中,则返回 true。否则 返回 false。
如果关联属性未定义受支持的令牌,则抛出一个
TypeError。 tokenlist .value-
将关联的集合作为字符串返回。
可以设置此值,以更改关联的属性。
该对象的 支持的属性索引 是以下范围内的数字: 从零到该对象的 词元集合 的 大小 − 1,除非 词元集合 为 空, 在这种情况下,没有 支持的属性索引。
此
add(tokens…)
方法的步骤如下:
-
对于每个 token,来自 tokens:
-
如果 token 为空字符串,则 抛出 一个 "
SyntaxError"DOMException。 -
如果 token 包含任何 ASCII 空白字符,则 抛出 一个 "
InvalidCharacterError"DOMException。
-
-
运行 更新 步骤。
此
remove(tokens…)
方法的步骤如下:
-
对于每个 token,来自 tokens:
-
如果 token 为空字符串,则 抛出 一个 "
SyntaxError"DOMException。 -
如果 token 包含任何 ASCII 空白字符,则 抛出 一个 "
InvalidCharacterError"DOMException。
-
-
运行 更新步骤。
此 toggle(token, force)
方法的步骤如下:
-
如果 token 为空字符串,则 抛出 一个 "
SyntaxError"DOMException。 -
如果 token 包含任何 ASCII 空白字符,则 抛出 一个 "
InvalidCharacterError"DOMException。 -
否则,如果 force 未给定或为 true,则 追加 token 到 this 的 词元集合,运行 更新步骤,并返回 true。
-
返回 false。
这些 更新步骤 并非每次都会为 toggle()
运行,这是出于 Web 兼容性的考虑。
此
replace(token, newToken)
方法的步骤如下:
-
如果 token 或 newToken 中任意一个为空字符串,则 抛出 一个 "
SyntaxError"DOMException。 -
如果 token 或 newToken 中任意一个包含任何 ASCII 空白字符,则 抛出 一个 "
InvalidCharacterError"DOMException。 -
运行 更新步骤。
-
返回 true。
这些 更新步骤 并非每次都会为 replace()
运行,这是出于 Web 兼容性的考虑。
此
supports(token)
方法的步骤如下:
-
令 result 为以下 验证步骤 的返回值,调用时使用 token。
-
返回 result。
8. XPath
DOM Level 3 XPath 定义了一个用于评估XPath 1.0表达式的 API。 这些 API 被广泛实现,但未得到维护。接口定义在此保留,以便在 Web IDL 发生变化时可以更新。 完整的这些 API 的定义仍然是必要的,此类工作已被跟踪并可以在 whatwg/dom#67 中贡献。 [DOM-Level-3-XPath] [XPath] [WEBIDL]
8.1.
接口 XPathResult
[Exposed =Window ]interface {XPathResult const unsigned short = 0;ANY_TYPE const unsigned short = 1;NUMBER_TYPE const unsigned short = 2;STRING_TYPE const unsigned short = 3;BOOLEAN_TYPE const unsigned short = 4;UNORDERED_NODE_ITERATOR_TYPE const unsigned short = 5;ORDERED_NODE_ITERATOR_TYPE const unsigned short = 6;UNORDERED_NODE_SNAPSHOT_TYPE const unsigned short = 7;ORDERED_NODE_SNAPSHOT_TYPE const unsigned short = 8;ANY_UNORDERED_NODE_TYPE const unsigned short = 9;FIRST_ORDERED_NODE_TYPE readonly attribute unsigned short ;resultType readonly attribute unrestricted double ;numberValue readonly attribute DOMString ;stringValue readonly attribute boolean ;booleanValue readonly attribute Node ?;singleNodeValue readonly attribute boolean ;invalidIteratorState readonly attribute unsigned long ;snapshotLength Node ?();iterateNext Node ?(snapshotItem unsigned long ); };index
8.2.
接口 XPathExpression
[Exposed =Window ]interface { // XPathResult.ANY_TYPE = 0XPathExpression XPathResult (evaluate Node ,contextNode optional unsigned short = 0,type optional XPathResult ?=result null ); };
8.3.
混入 XPathEvaluatorBase
callback interface {XPathNSResolver DOMString ?(lookupNamespaceURI DOMString ?); };prefix interface mixin { [XPathEvaluatorBase NewObject ]XPathExpression (createExpression DOMString ,expression optional XPathNSResolver ?=resolver null );Node createNSResolver (Node ); // legacy // XPathResult.ANY_TYPE = 0nodeResolver XPathResult (evaluate DOMString ,expression Node ,contextNode optional XPathNSResolver ?=resolver null ,optional unsigned short = 0,type optional XPathResult ?=result null ); };Document includes XPathEvaluatorBase ;
createNSResolver(nodeResolver)
方法步骤是返回 nodeResolver。
此方法仅因历史原因存在。
8.4.
接口 XPathEvaluator
[Exposed =Window ]interface {XPathEvaluator (); };constructor XPathEvaluator includes XPathEvaluatorBase ;
由于历史原因,你既可以构造 XPathEvaluator
,也可以在 Document
上访问相同的
方法。
9. XSLT
请避免在浏览器中使用客户端 XSLT。浏览器对 XSLT 的实现 极易出现内存安全漏洞,而 Web 平台已逐渐转向 使用 JavaScript 作为安全替代方案。因此,此功能正在 从 Web 平台中移除。(这是一个需要多年时间的漫长过程。)
XSL Transformations (XSLT) 是一种将 XML 文档转换为其他 XML 文档的语言。 本节定义的 API 已被广泛实现,并在此保留,以便在 Web IDL 发生变化时可以更新。 这些 API 的完整定义仍然是必要的,此类工作已被跟踪并可以在 whatwg/dom#181 中贡献。 [XSLT]
9.1.
接口 XSLTProcessor
[Exposed =Window ]interface {XSLTProcessor ();constructor undefined (importStylesheet Node ); [style CEReactions ]DocumentFragment (transformToFragment Node ,source Document ); [output CEReactions ]Document (transformToDocument Node );source undefined ([setParameter LegacyNullToEmptyString ]DOMString ,namespaceURI DOMString ,localName any );value any ([getParameter LegacyNullToEmptyString ]DOMString ,namespaceURI DOMString );localName undefined ([removeParameter LegacyNullToEmptyString ]DOMString ,namespaceURI DOMString );localName undefined ();clearParameters undefined (); };reset
10. 安全和隐私考虑
此标准没有已知的安全或隐私考虑。
11. 历史
此标准曾包含多个已被移除的接口和接口成员。
这些接口已被移除:
DOMConfigurationDOMErrorDOMErrorHandlerDOMImplementationListDOMImplementationSourceDOMLocatorDOMObjectDOMUserDataEntityEntityReferenceMutationEventMutationNameEventNameListNotationRangeExceptionTypeInfoUserDataHandler
这些接口成员已被移除:
Attr-
schemaTypeInfoisId
Document-
createEntityReference()xmlEncodingxmlStandalonexmlVersionstrictErrorCheckingdomConfignormalizeDocument()renameNode()
DocumentType-
entitiesnotationsinternalSubset
DOMImplementation-
getFeature()
Element-
schemaTypeInfosetIdAttribute()setIdAttributeNS()setIdAttributeNode()
Node-
isSupportedgetFeature()getUserData()setUserData()
NodeIterator-
expandEntityReferences
Text-
isElementContentWhitespacereplaceWholeText()
TreeWalker-
expandEntityReferences
致谢
多年来,许多人为使 DOM 更具互操作性作出了贡献,从而促进了该标准的目标。同样,许多人也为使该标准发展至今做出了帮助。
因此,特别感谢以下人士: Adam Klein, Adrian Bateman, Ahmid snuggs, Alex Komoroske, Alex Russell, Alexey Shvayka, Andreas Kling, Andreu Botella, Anthony Ramine, Arkadiusz Michalski, Armen Michaeli, Arnaud Le Hors, Arun Ranganathan, Benjamin Gruenbaum, Björn Höhrmann, Boris Zbarsky, Brandon Payton, Brandon Slade, Brandon Wallace, Brian Kardell, C. Scott Ananian, Cameron McCormack, Chris Dumez, Chris Paris, Chris Rebert, Cyrille Tuzi, Dan Burzo, Daniel Clark, Daniel Glazman, Darien Maillet Valentine, Darin Fisher, David Baron, David Bruant, David Flanagan, David Håsäther, David Hyatt, Deepak Sherveghar, Dethe Elza, Dimitri Glazkov, Domenic Denicola, Dominic Cooney, Dominique Hazaël-Massieux, Don Jordan, Doug Schepers, Edgar Chen, Elisée Maurer, Elliott Sprehn, Emilio Cobos Álvarez, Eric Bidelman, Erik Arvidsson, Evgeny Kapun, François Daoust, François Remy, Gary Kacmarcik, Gavin Nicol, Giorgio Liscio, Glen Huang, Glenn Adams, Glenn Maynard, Hajime Morrita, Harald Alvestrand, Hayato Ito, Henri Sivonen, Hongchan Choi, Hunan Rostomyan, Ian Hickson, Igor Bukanov, Jacob Rossi, Jake Archibald, Jake Verbaten, James Graham, James Greene, James M Snell, James Robinson, Jayson Chen, Jeffrey Yasskin, Jens Lindström, Jeremy Davis, Jesse McCarthy, Jinho Bang, João Eiras, Joe Kesselman, John Atkins, John Dai, Jonas Sicking, Jonathan Kingston, Jonathan Robie, Joris van der Wel, Joshua Bell, J. S. Choi, Jungkee Song, Justin Summerlin, Kagami Sascha Rosylight, 呂康豪 (Kang-Hao Lu), 田村健人 (Kent TAMURA), Kevin J. Sung, Kevin Sweeney, Kirill Topolyan, Koji Ishii, Lachlan Hunt, Lauren Wood, Luca Casonato, Luke Zielinski, Magne Andersson, Majid Valipour, Malte Ubl, Manish Goregaokar, Manish Tripathi, Marcos Caceres, Mark Miller, Martijn van der Ven, Mason Freed, Mats Palmgren, Mounir Lamouri, Michael Stramel, Michael™ Smith, Mike Champion, Mike Taylor, Mike West, Nicolás Peña Moreno, Nidhi Jaju, Ojan Vafai, Oliver Nightingale, Olli Pettay, Ondřej Žára, Peter Sharpe, Philip Jägenstedt, Philippe Le Hégaret, Piers Wombwell, Pierre-Marie Dartus, prosody—Gab Vereable Context(, Rafael Weinstein, Rakina Zata Amni, Richard Bradshaw, Rick Byers, Rick Waldron, Robbert Broersma, Robin Berjon, Roland Steiner, Rune F. Halvorsen, Russell Bicknell, Ruud Steltenpool, Ryosuke Niwa, Sam Dutton, Sam Sneddon, Samuel Giles, Sanket Joshi, Scott Haseley, Sebastian Mayr, Seo Sanghyeon, Sergey G. Grekhov, Shiki Okasaka, Shinya Kawanaka, Simon Pieters, Simon Wülker, Stef Busking, Steve Byrne, Steven Obiajulu, Stig Halvorsen, Tab Atkins, Takashi Sakamoto, Takayoshi Kochi, Theresa O’Connor, Theodore Dubois, timeless, Timo Tijhof, Tobie Langel, Tom Pixley, Travis Leithead, Trevor Rowbotham, triple-underscore, Tristan Fraipont, Veli Şenol, Vidur Apparao, Warren He, Xidorn Quan, Yash Handa, Yehuda Katz, Yoav Weiss, Yoichi Osato, Yoshinori Sano, Yu Han, Yusuke Abe, 和 Zack Weinberg, 感谢你们的出色贡献!
本标准由Anne van Kesteren (Apple, annevk@annevk.nl)编写,并得到了Aryeh Gregor (ayg@aryeh.name)和Ms2ger (ms2ger@gmail.com)的实质性贡献。
知识产权
版权所有 © WHATWG (Apple, Google, Mozilla, Microsoft)。本作品根据知识共享署名 4.0 国际许可协议进行许可。如果其部分内容被整合到源代码中,则源代码中的这些部分将根据 BSD 3-Clause 许可证进行许可。
这是现行标准。那些对专利审查版本感兴趣的人应该查看现行标准审查草案。