1. 基础设施
本规范依赖于现行标准的基础设施标准。[INFRA]
本规范中使用的一些术语在编码、选择器、受信任类型、Web IDL、XML和XML中的命名空间中有定义。 [ENCODING] [SELECTORS4] [TRUSTED-TYPES] [WEBIDL] [XML] [XML-NAMES]
当需要扩展时,可以相应地更新 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,请执行以下步骤:
-
令s为解析选择器selectors的结果。[SELECTORS4]
-
如果s失败,则抛出一个"
SyntaxError"DOMException。 -
返回将选择器与树匹配的结果,其中s与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 (>),则它是一个有效的文档类型名称。
空字符串是一个有效的文档类型名称。
要验证并提取一个 namespace 和 qualifiedName,给定一个 context:
-
如果 namespace 是空字符串,则将其设置为 null。
-
将 prefix 设置为 null。
-
将 localName 设置为 qualifiedName。
-
如果 qualifiedName 包含 U+003A (:):
-
将 splitResult 设置为运行 严格拆分的结果,参数为 qualifiedName 和 U+003A (:)。
-
将 prefix 设置为 splitResult[0]。
-
将 localName 设置为 splitResult[1]。
-
如果 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) { // great success …}
事件监听器可以通过使用removeEventListener()方法删除,传递相同的参数。
或者,也可以通过将AbortSignal传递给addEventListener(),然后调用控制器上持有信号的abort()来删除事件监听器。
事件也是对象,并实现了Event接口(或派生接口)。在上面的例子中,ev是事件。ev作为参数传递给事件监听器的回调(通常是如上所示的JavaScript函数)。事件监听器通过事件的type属性值(上例中的"load")来区分事件。事件的target属性值返回事件被派发到的对象(如上例中的obj)。
虽然事件通常由用户代理在用户交互或某些任务完成时派发,但应用程序可以通过使用通常称为合成事件的方式派发事件。
// add an appropriate event listener obj. addEventListener( "cat" , function ( e) { process( e. detail) }) // create and dispatch the event var event= new CustomEvent( "cat" , { "detail" : { "hazcheeseburger" : true }}) obj. dispatchEvent( event)
除了用于传递信号外,事件有时也用于让应用程序控制操作中的后续步骤。例如,作为表单提交的一部分,type属性值为"submit"的事件被派发。如果调用了该事件的preventDefault()方法,则表单提交将被终止。希望通过应用程序事件(合成事件)派发该功能的应用程序,可以使用dispatchEvent()方法的返回值。
if ( obj. dispatchEvent( event)) { // event was not canceled, time for some magic …}
当一个事件被派发到一个参与树(例如,一个元素)的对象时,它也可以到达该对象的祖先上的事件监听器。实际上,该对象的所有包含祖先中捕获为true的事件监听器都将按照树的顺序被调用。然后,如果事件的bubbles为true,则该对象的所有包含祖先中捕获为false的事件监听器将按照相反的树的顺序被调用。
<!doctype html> < html > < head > < title > Boring example</ title > </ head > < body > < p > Hello< span id = x > world</ 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属性值将是document,第二次将是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 ; // legacyreadonly 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 ; // legacy alias of .stopPropagation()undefined stopImmediatePropagation ();readonly attribute boolean bubbles ;readonly attribute boolean cancelable ;attribute boolean returnValue ; // legacyundefined 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 ); // legacy };dictionary {EventInit boolean =bubbles false ;boolean =cancelable false ;boolean =composed false ; };
一个Event对象通常被称为一个事件。它用于标识某些事情已经发生,例如,一个图像已经完成下载。
一个潜在事件目标是 null 或一个EventTarget对象。
一个事件有一个关联的目标(一个潜在事件目标)。除非另有说明,否则它为 null。
一个事件有一个关联的相关目标(一个潜在事件目标)。除非另有说明,否则它为 null。
其他规范使用相关目标来定义一个relatedTarget属性。[UIEVENTS]
一个事件有一个关联的触摸目标列表(一个列表,包含零个或多个潜在事件目标)。除非另有说明,否则它为空列表。
触摸目标列表专门用于定义TouchEvent接口和相关接口。[TOUCH-EVENTS]
一个事件有一个关联的路径。一个路径是一个列表,包含结构体。每个结构体由一个调用目标(一个EventTarget对象)、一个在 shadow 树中的调用目标(一个布尔值)、一个shadow 调整后的目标(一个潜在事件目标)、一个相关目标(一个潜在事件目标)、一个触摸目标列表(一个列表,包含潜在事件目标)、一个关闭树的根(一个布尔值)和一个关闭树中的插槽(一个布尔值)。一个路径最初为空列表。
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的调用目标对象(将在其上调用侦听器的对象),但不包括任何节点,这些节点在shadow 树中,其shadow root的模式为"
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 时调用,并且在执行带有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 时:
-
如果path[index]的关闭树的根为 true,则将currentHiddenLevel增加 1。
-
如果currentHiddenLevel小于或等于maxHiddenLevel,则前置path[index]的调用目标到composedPath。
-
如果 path[index] 的 slot-in-closed-tree 为 true:
-
将currentHiddenLevel减少 1。
-
如果currentHiddenLevel小于maxHiddenLevel,则将maxHiddenLevel设为currentHiddenLevel。
-
-
减少index的值 1。
-
-
将currentHiddenLevel和maxHiddenLevel设为currentTargetHiddenSubtreeLevel。
-
将index设为currentTargetIndex + 1。
-
当index小于path的大小时:
-
如果path[index]的关闭树中的插槽为 true,则将currentHiddenLevel增加 1。
-
如果currentHiddenLevel小于或等于maxHiddenLevel,则追加path[index]的调用目标到composedPath。
-
如果 path[index] 的 root-of-closed-tree 为 true:
-
将currentHiddenLevel减少 1。
-
如果currentHiddenLevel小于maxHiddenLevel,则将maxHiddenLevel设为currentHiddenLevel。
-
-
增加index的值 1。
-
-
返回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属性必须返回初始化时的值。
要初始化一个event,使用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和一个EventIniteventInitDict,如内部事件创建步骤中所示。
这个构造方式可用于Event子类,它们具有比简单的初始化字典成员和IDL属性之间一对一映射更复杂的结构。
要使用eventInterface 创建事件,该接口必须是Event或继承自它的接口,并且可选地提供realm realm,运行以下步骤:
-
如果未提供realm,则将其设置为null。
-
将dictionary设置为将JavaScript值undefined转换为eventInterface构造函数所接受的字典类型的结果。(此字典类型将是
EventInit或继承自它的字典类型。)如果需要成员,这种方法不起作用;请参见whatwg/dom#600。
-
运行内部事件创建步骤,以eventInterface、realm、该事件信号发生的时间和dictionary为参数,得到event。
-
将event的
isTrusted属性初始化为true。 -
返回event。
创建事件用于需要分别创建和分发事件的其他规范,而不是简单地触发事件。它确保事件的属性初始化为正确的默认值。
内部事件创建步骤,给定eventInterface、realm、time和dictionary,如下所示:
-
使用eventInterface创建一个新对象作为event的结果。如果realm非空,则使用该realm;否则,使用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为true时,监听器在捕获阶段触发;当为false或未设置时,监听器在冒泡阶段触发。无论设置如何,若事件处于目标阶段,监听器均会被触发。
当options设置为true时,表示监听器为被动模式,不会调用
preventDefault()来取消事件。当options设置为true时,表示监听器仅触发一次,触发后将被移除。
若为options指定了
AbortSignal,当信号被中止时,监听器将被移除。若已存在相同type、callback和capture的事件监听器,则不会再次添加。
target . removeEventListener(type, callback [, options])-
移除target中与type、callback和options匹配的事件监听器。
target . dispatchEvent(event)-
派发event事件,并返回true,若事件的
cancelable属性为false或未调用preventDefault(),否则返回false。
要展开 options,请执行以下步骤:
-
如果options是布尔值,则返回options。
-
返回options["
capture"]。
要进一步展开 options,请执行以下步骤:
new EventTarget()构造函数步骤不执行任何操作。
由于其他地方声明的默认值,返回的EventTarget的 获取父级算法将返回null,并且它没有激活行为、遗留预激活行为, 或遗留取消激活行为。
将来我们可能会允许自定义获取父级算法。请告诉我们 这对您的程序是否有用。目前,所有作者创建的EventTarget 不参与树结构。
默认被动值,给定一个事件类型type和一个EventTarget eventTarget,由下列步骤决定:
要添加事件监听器,给定一个EventTarget 对象eventTarget和一个事件监听器listener,请执行以下步骤:
-
若eventTarget是一个
ServiceWorkerGlobalScope对象,其service worker的脚本资源的曾经评估过的标志被设置,且listener的类型与任何service worker 事件的类型属性值匹配,则向控制台报告一个警告,提示这可能不会产生预期结果。[SERVICE-WORKERS] -
若listener的回调为null,则返回。
-
若listener的被动为null,则将其设置为listener的默认被动值,根据listener的类型 和eventTarget。
-
若eventTarget的事件监听器列表不包含一个事件监听器,其类型是listener的类型,回调是listener的回调,且捕获是listener的捕获,则追加 listener到eventTarget的事件监听器列表中。
-
- 移除事件监听器,使用eventTarget和listener。
添加事件监听器的概念是为了确保事件处理器使用相同的代码路径。[HTML]
addEventListener(type, callback, options) 方法步骤为:
要移除事件监听器,给定一个EventTarget 对象eventTarget和一个事件监听器 listener,请执行以下步骤:
-
如果eventTarget是
ServiceWorkerGlobalScope对象,并且它的Service Worker的要处理的事件类型集合包含listener的类型,那么报告一个警告到控制台,表明这可能不会产生预期的结果。[SERVICE-WORKERS]
HTML 需要这个来定义事件处理器。[HTML]
要移除所有事件监听器,给定一个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的设计使得要高效实现它们就需要观察事件侦听器。这使得侦听器的存在是可观察的,即使是空的侦听器也可能对应用程序的行为产生显著的性能影响。例如,可以用于阻止异步滚动的触摸和滚轮事件。在某些情况下,可以通过仅在存在至少一个非被动侦听器时将事件指定为可取消来缓解这一问题。例如,非被动触摸事件侦听器必须阻止滚动,但如果所有侦听器都是被动的,则可以通过使触摸事件不可取消(从而忽略对preventDefault()的调用)来允许滚动并行开始。因此,分派事件的代码能够观察到非被动侦听器的缺失,并使用该信息来清除正在分派的事件的可取消属性。
理想情况下,任何新的事件API都应定义为不需要此属性。(请使用whatwg/dom进行讨论。)
要获取遗留的Service Worker获取事件侦听器回调,给定一个ServiceWorkerGlobalScopeglobal,请运行以下步骤。这些步骤将返回一个EventListener对象的列表。
2.9. 分发事件
要将一个事件分发给一个目标,可选带有legacy target override flag和legacyOutputDidListenersThrowFlag,请按以下步骤操作:
-
设置event的分发标志。
-
如果未给出legacy target override flag,则将targetOverride设置为目标,否则设置为目标的关联的
文档。[HTML]legacy target override flag仅由HTML使用,且仅当目标是一个
窗口对象时使用。 -
将activationTarget设置为null。
-
将relatedTarget设置为针对目标重新定位event的relatedTarget的结果。
-
设 clearTargets 为 false。
-
如果 target 不是 relatedTarget 或者 target 是 event 的 relatedTarget:
-
将touchTargets设置为一个新的列表。
-
对于每个touchTarget,它在event的触摸目标列表中: 追加针对目标重新定位touchTarget的结果到touchTargets中。
-
通过event、目标、targetOverride、relatedTarget、touchTargets,并设置为false,附加到事件路径。
-
如果event是一个
鼠标事件对象,且event的类型属性为"click",则isActivationEvent为true;否则为false。 -
如果isActivationEvent为true且目标具有激活行为,则将activationTarget设置为目标。
-
将slot-in-closed-tree设置为false。
-
将parent设置为调用目标的获取父项结果的event。
-
当parent非空时:
-
如果slottable非空:
-
将relatedTarget设置为针对parent重新定位event的relatedTarget的结果。
-
将touchTargets设置为一个新的列表。
-
对于每个touchTarget ,它在event的触摸目标列表中: 追加针对parent重新定位touchTarget的结果到touchTargets中。
-
如果parent是一个
窗口对象,或parent是一个节点且目标的根是parent的包括影子在内的包容性祖先,则: -
否则,如果parent是relatedTarget,则将parent设置为null。
-
否则:
-
如果parent非空,则将parent设置为调用parent的获取父项结果的event。
-
将slot-in-closed-tree设置为false。
-
-
如果 clearTargetsStruct 的 shadow-adjusted target、clearTargetsStruct 的 relatedTarget,或 clearTargetsStruct 的 touch target list 中的
EventTarget对象是一个节点,其根是一个影子根:则将 clearTargets 设置为 true。 -
如果activationTarget非空且activationTarget具有旧式预激活行为,则运行activationTarget的旧式预激活行为。
-
-
将event的
当前目标属性设置为null。 -
将event的路径设置为空列表。
-
如果 clearTargets 为 true:
-
将event的目标设置为null。
-
将event的relatedTarget设置为null。
-
将event的触摸目标列表设置为空列表。
-
-
如果activationTarget非空:
-
如果event的取消标志已设置,则返回false;否则返回true。
要附加到事件路径,给定一个event、invocationTarget、shadowAdjustedTarget、relatedTarget、touchTargets,以及slot-in-closed-tree,请运行这些步骤:
-
将invocationTargetInShadowTree设置为false。
-
如果invocationTarget是一个节点,且其根是一个影子根,则将invocationTargetInShadowTree设置为true。
-
将root-of-closed-tree设置为false。
-
如果invocationTarget是一个影子根,且其模式是"
closed",则将root-of-closed-tree设置为true。 -
追加一个新的结构到event的路径,其调用目标是invocationTarget,调用目标在影子树中是invocationTargetInShadowTree,影子调整目标是shadowAdjustedTarget,relatedTarget是relatedTarget,触摸目标列表是touchTargets,关闭树的根是root-of-closed-tree,以及slot-in-closed-tree是slot-in-closed-tree。
要调用,给定一个struct、event、阶段,以及可选的legacyOutputDidListenersThrowFlag,请运行这些步骤:
-
将event的目标设置为event的路径中的最后一个结构,其影子调整目标非空,且为struct或struct之前的结构。
-
将event的relatedTarget设置为struct的relatedTarget。
-
如果event的停止传播标志已设置,则返回。
-
将invocationTargetInShadowTree设置为struct的调用目标在影子树中。
-
将found设置为运行内部调用通过event、listeners、阶段、invocationTargetInShadowTree,以及如果给出的话legacyOutputDidListenersThrowFlag的结果。
-
如果 found 为 false 且 event 的
isTrusted属性为 true:-
将originalEventType设置为event的
类型属性值。 -
如果event的
类型属性值匹配下表中的任意字符串,将event的类型属性值设置为同一行匹配字符串旁的字符串,否则返回。事件类型 旧式事件类型 " animationend"" webkitAnimationEnd"" animationiteration"" webkitAnimationIteration"" animationstart"" webkitAnimationStart"" transitionend"" webkitTransitionEnd" -
内部调用通过event、listeners、阶段、invocationTargetInShadowTree,以及如果给出的话legacyOutputDidListenersThrowFlag。
-
将event的
类型属性值设置为originalEventType。
-
要内部调用,给定一个event、listeners、阶段、invocationTargetInShadowTree,以及可选的legacyOutputDidListenersThrowFlag,请运行这些步骤:
-
让 found 为 false。
-
对于 listeners 中的每个 listener,其 removed 为 false:
-
将 found 设为 true。
-
如果 listener 的 once 为 true,则根据 event 的
currentTarget属性值和 listener 移除一个事件侦听器。 -
让 currentEvent 为 undefined。
-
如果 global 是一个
Window对象: -
如果 global 是一个
Window对象,则 记录事件监听器的计时信息,使用 event 和 listener。 -
调用用户对象的操作,使用 listener 的 回调,"
handleEvent",«event»,以及 event 的currentTarget属性值。如果这会抛出一个异常 exception:-
设置 legacyOutputDidListenersThrowFlag(如果提供)。
legacyOutputDidListenersThrowFlag 仅被 Indexed Database API 使用。[INDEXEDDB]
-
取消设定 event 的 被动监听器标志。
-
返回 found。
2.10. 触发事件
要在target上触发事件,事件名为e,可选地使用eventConstructor,并描述如何初始化IDL属性,以及legacy target override flag,请执行以下步骤:
在 DOM 的上下文中,"Fire" 是创建、初始化和分派一个事件的缩写。Fire an event 使得这个过程更容易表达。
如果事件需要其 bubbles 或cancelable 属性初始化, 可以这样写:“fire an event named submit at target with its cancelable attribute initialized to true”。
或者,当需要自定义构造函数时,可以这样写:“fire an event named click at target using MouseEvent with its detail attribute initialized to 1”。
有时返回值很重要:
-
让 doAction 成为 firing an event named
likeat target 的结果。 -
如果 doAction 为真,那么……
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 could be implemented as follows:
function doAmazingness({ signal}) { return new Promise(( resolve, reject) => { signal. throwIfAborted(); // Begin doing amazingness, and call resolve(result) when done. // But also, watch for signals: signal. addEventListener( 'abort' , () => { // Stop doing amazingness, and: 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未定义,则会存储一个"AbortError"DOMException。
一个AbortController对象有一个关联的信号(一个AbortSignal对象)。
new AbortController()构造函数步骤如下:
-
让signal成为一个新的
AbortSignal对象。
signal的getter步骤是返回this的signal。
abort(reason)方法步骤是在signal abort上执行,带有reason如果给定。
在AbortController的controller上带有可选的reason执行signal abort,如果reason被提供。
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(如果未定义则为"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值),其初始状态为未定义。
一个AbortSignal对象有一个关联的中止算法(一组将在中止时执行的算法),其初始状态为空。
中止算法使得具有复杂要求的API能够合理地响应abort()。例如,给定API的中止原因可能需要传播到跨线程环境,例如service worker。
一个AbortSignal对象有一个依赖项(一个布尔值),其初始状态为false。
一个AbortSignal对象有一个关联的源信号(一组AbortSignal对象),其初始状态为空。
一个AbortSignal对象有一个关联的依赖信号(一组依赖于对象的AbortSignal对象),其初始状态为空。
静态方法abort(reason)的步骤如下:
-
让signal成为一个新的
AbortSignal对象。 -
将signal的中止原因设置为reason,如果给定;否则设置为新的"
AbortError"DOMException。 - 返回signal。
静态方法timeout(milliseconds)的步骤如下:
-
让signal成为一个新的
AbortSignal对象。 -
让global成为signal的相关全局对象。
-
在超时后运行步骤,给定global、"
AbortSignal-timeout"、milliseconds,以及以下步骤:-
在全局任务队列中排队,在global上,基于signal和新的"
TimeoutError"DOMException执行signal abort。
在此超时时间内,如果signal已为其
abort事件注册了任何事件监听器,则必须从global到signal保持一个强引用。 -
-
返回signal。
静态方法any(signals)的步骤是返回创建一个依赖的中止信号的结果,使用signals、AbortSignal和当前领域。
abortedgetter步骤是返回true如果this已中止;否则返回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 是一个 事件处理程序 IDL 属性,用于 onabort 事件处理程序,其 事件处理程序事件类型 是 abort。
对 AbortSignal 对象的更改代表了相应的 AbortController 对象的意图,但观察 AbortSignal 对象的 API 可以选择忽略这些更改。例如,如果操作已经完成。
当 AbortSignal 对象的 中止原因 不为未定义时, 该对象被认为是 已中止。
要向 AbortSignal 对象 signal 中 添加 一个算法 algorithm:
要从 AbortSignal signal 中移除一个算法 algorithm,请从 signal 的中止算法中移除 algorithm。
要 发出中止信号, 给定一个 AbortSignal 对象 signal 和一个可选的 reason:
-
如果 signal 已经 中止,则返回。
-
将 signal 的 中止原因 设为 reason(如果提供);否则设为一个新的 "
AbortError"DOMException。 -
将 dependentSignalsToAbort 设为一个新的 列表。
-
运行中止步骤 对于 signal。
-
对于每个 dependentSignal 在 dependentSignalsToAbort 中,运行中止步骤 对于 dependentSignal。
要 运行中止步骤 对于一个 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对象的更改,并以不导致与其他观察者冲突的方式执行此操作。
不使用 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空白字符都被转化为文本节点,但总体概念是清晰的。标记进入,树形节点输出。
可以使用非常棒的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-
按树顺序:
-
可选地包含一个
DocumentType节点。 -
零个或多个
ProcessingInstruction或Comment节点。
DocumentFragmentElement-
零个或多个
Element或CharacterData节点。 DocumentTypeCharacterDataAttr-
没有子节点。
Attr节点参与一个树的历史原因;它们从不具有(非空)父节点或任何子节点,因此在一个树中是孤立的。
要确定节点node的长度,请执行以下步骤:
-
如果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 之前时,执行如下步骤:
-
如果 parent 不是
Document、DocumentFragment或Element节点,则抛出一个“HierarchyRequestError”DOMException。 -
如果 node 是 parent 的宿主包含的祖先节点,则抛出一个“
HierarchyRequestError”DOMException。 -
如果 child 非空且其父节点不是 parent,则抛出一个“
NotFoundError”DOMException。 -
如果 node 不是
DocumentFragment、DocumentType、Element或CharacterData节点,则抛出一个“HierarchyRequestError”DOMException。 -
如果 node 是一个
Text节点且 parent 是一个文档,或者 node 是一个文档类型且 parent 不是一个文档,则抛出一个“HierarchyRequestError”DOMException。 -
如果 parent 是一个文档,并且以下根据 node 实现的接口切换的任何语句为真,则抛出一个“
HierarchyRequestError”DOMException。
Specifications 可能为全部或部分 nodes 定义 insertion steps。该算法会接收 insertedNode,如下面 insert 算法所示。该等步骤不得修改 node tree(即 insertedNode 所参与的树),不得创建 browsing contexts、fire events,或以其他方式执行 JavaScript。不过,这些步骤可以通过 queue tasks 来异步完成这些操作。
虽然插入步骤不能执行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)' ; // Logs 'rgb(255, 0, 0)' style. innerText = 'h1 {color: rgb(255, 0, 0);}' ; document. body. append( fragment); 上例中的脚本记录了,因为以下事件按顺序发生:
相关规范 也可以为所有或部分 nodes 定义 post-connection steps。该算法接收 connectedNode, 如下面 insert 算法所示。
执行 post-connection steps 的目的是为 nodes 提供机会去执行任何与连接相关的操作,这些操作可能会修改 node tree(即 connectedNode 所 participates 的树)、创建 浏览上下文,或以其他方式执行 JavaScript。这些步骤允许一批 nodes 就脚本而言作为一个 原子操作被 inserted, 所有主要的副作用都在将该批次插入到 node tree 完成之后发生。这确保了所有挂起的 node tree 插入在更多插入发生之前完全完成。
相关规范 可能为所有或部分 nodes 定义 children changed steps。该算法不接收参数,由 insert、remove 与 replace data 调用。
要 insert 一个 node node 到一个 node parent 中,在 null 或一个 node child 之前,可选地带有布尔型 suppressObservers(默认 false):
-
令 nodes 为 node 的 children,如果 node 是一个
DocumentFragmentnode;否则为 « node »。 -
令 count 为 nodes 的 size。
-
如果 count 为 0,则返回。
-
如果 node 是一个
DocumentFragmentnode:-
Remove 其 children,并将 suppressObservers 设为 true。
-
Queue a tree mutation record,为 node 排队,参数为 « »、nodes、null 和 null。
此步骤故意不考虑 suppressObservers。
-
-
如果 child 非空:
-
对于每个其 start node 为 parent 且 start offset 大于 child 的 index 的 live range:将其 start offset 增加 count。
-
对于每个其 end node 为 parent 且 end offset 大于 child 的 index 的 live range:将其 end offset 增加 count。
-
-
令 previousSibling 为 child 的 previous sibling;如果 child 为 null,则为 parent 的 last child。
-
对于 nodes 中的每个 node,按 tree order:
-
Adopt 该 node 到 parent 的 node document。
-
否则,insert 该 node 到 parent 的 children,插入位置为 child 的 index 之前。
-
如果 parent 是一个 shadow host,且其 shadow root 的 slot assignment 为 "
named", 并且 node 是一个 slottable,则为 node assign a slot。 -
如果 parent 的 root 是一个 shadow root,且 parent 是一个 slot 并且其 assigned nodes 为空表, 则对 parent 运行 signal a slot change。
-
运行 assign slottables for a tree,参数为 node 的 root。
-
对于 node 的每个 shadow-including inclusive descendant inclusiveDescendant,按 shadow-including tree order:
-
用 插入步骤处理 inclusiveDescendant。
-
如果 inclusiveDescendant 是 元素且 inclusiveDescendant 的 自定义元素注册表不为 null:
-
如果 inclusiveDescendant 的 自定义元素注册表 的 “is scoped” 属性为 true,则 追加 inclusiveDescendant 的 节点文档到 inclusiveDescendant 的 自定义元素注册表的 文档作用域集合。
-
如果 inclusiveDescendant 是 自定义,则 将一个自定义元素回调反应入队, 其参数为 inclusiveDescendant, 回调名 "
connectedCallback",以及 « »。 -
否则,尝试升级 inclusiveDescendant。
如果此步骤成功升级了 inclusiveDescendant,则其
connectedCallback会在 升级元素算法期间自动入队。
-
-
否则,如果 inclusiveDescendant 是 shadow root, inclusiveDescendant 的 自定义元素注册表 不为 null, 并且 inclusiveDescendant 的 自定义元素注册表 的 “is scoped” 属性为 true,则 追加 inclusiveDescendant 的 节点文档到 inclusiveDescendant 的 自定义元素注册表的 文档作用域集合。
-
-
-
如果 suppressObservers 为 false,则为 parent 排队一个 tree mutation record,参数为 nodes、« »、previousSibling 与 child。
-
为 parent 运行 children changed steps。
-
令 staticNodeList 为一个list,其内容类型为 nodes,初始为 « »。
我们在对任一节点运行 post-connection steps 之前 收集所有 nodes,而不是在遍历 node tree 时一边遍历一边调用 post-connection steps。这是因为 post-connection steps 可能会修改树的结构,使得实时遍历不安全, 可能导致对同一 node 多次调用 post-connection steps。
-
对于 nodes 中的每个 node,按 tree order:
-
对于 node 的每个 shadow-including inclusive descendant inclusiveDescendant,按 shadow-including tree order: append inclusiveDescendant 到 staticNodeList。
-
-
For each node of staticNodeList:如果 node 是 connected, 则运行 post-connection steps,参数为该 node。
要 append 一个 node node 到一个 node parent: pre-insert node 到 parent 的 null 之前。
规范 可能为全部或部分 nodes 定义 moving steps。该算法会传入一个 node movedNode,以及一个 node-or-null oldParent,如下面的 move 算法所示。像 insertion steps 一样,这些步骤不得修改 node tree(即 movedNode 所参与的树)、创建 browsing contexts、fire events,或以其他方式执行 JavaScript。不过,这些步骤可以将任务排入队列以异步完成这些操作。
要 move 一个 node node 到一个 node newParent 中, 在 null 或一个 node child 之前:
-
如果 newParent 的 shadow-including root 与 node 的 shadow-including root 不同,则 throw 一个 "
HierarchyRequestError"DOMException。这具有副作用:确保只有当 newParent 的 connected 与 node 的 connected 相同时才执行移动。
-
如果 node 是 newParent 的 host-including inclusive ancestor, 则 throw 一个 "
HierarchyRequestError"DOMException。 -
如果 child 非空且其 parent 不是 newParent,则 throw 一个 "
NotFoundError"DOMException。 -
如果 node 既不是
Element也不是CharacterData类型的 node, 则 throw 一个 "HierarchyRequestError"DOMException。 -
如果 node 是一个
Text节点,且 newParent 是一个 document, 则 throw 一个 "HierarchyRequestError"DOMException。 -
如果 newParent 是一个 document,且 node 是一个
Element节点, 并且以下情形之一为真:newParent 已经有一个 element 子节点、child 是一个 doctype,或 child 非空且有一个 doctype 在 child 的后面, 则 throw 一个 "HierarchyRequestError"DOMException。 -
令 oldParent 为 node 的 parent。
-
Assert:oldParent 非空。
-
运行 live range pre-remove steps,参数为 node。
-
对于每个其 root 的 node document 为 node 的 NodeIterator 对象 iterator:运行 NodeIterator pre-remove steps,参数为 node 与 iterator。
-
令 oldPreviousSibling 为 node 的 previous sibling。
-
令 oldNextSibling 为 node 的 next sibling。
-
如果 node 是 assigned,则对其 assigned slot 运行 assign slottables。
-
如果 oldParent 的 root 是 shadow root,且 oldParent 是一个 slot 且其 assigned nodes 为空表, 则对 oldParent 运行 signal a slot change。
-
如果 node 有一个作为 inclusive descendant 的 slot:
-
运行 assign slottables for a tree,参数为 oldParent 的 root。
-
运行 assign slottables for a tree,参数为 node。
-
-
如果 child 非空:
-
对于每个其 start node 为 newParent 且 start offset 大于 child 的 index 的 live range:将其 start offset 增加 1。
-
对于每个其 end node 为 newParent 且 end offset 大于 child 的 index 的 live range:将其 end offset 增加 1。
-
-
令 newPreviousSibling 为:如果 child 非空,则为 child 的 previous sibling;否则为 newParent 的 last child。
-
如果 newParent 是一个 shadow host,其 shadow root 的 slot assignment 为 "
named" 且 node 是一个 slottable,则为 node assign a slot。 -
如果 newParent 的 root 是 shadow root,且 newParent 是一个 slot 且其 assigned nodes 为空表, 则对 newParent 运行 signal a slot change。
-
运行 assign slottables for a tree,参数为 node 的 root。
-
对于 node 的每个 shadow-including inclusive descendant inclusiveDescendant,按 shadow-including tree order:
-
如果 inclusiveDescendant 是 node,则对其运行 moving steps, 参数为 inclusiveDescendant 与 oldParent。否则,运行 moving steps 参数为 inclusiveDescendant 与 null。
因为 move 算法 是独立于 insert 与 remove 的原语, 它不会为 inclusiveDescendant 调用传统的 insertion steps 或 removing steps。
-
如果 inclusiveDescendant 是 custom 且 newParent 是 connected,则以 inclusiveDescendant、 回调名 "
connectedMoveCallback" 及 « » 入队一个自定义元素回调反应。
-
-
Queue a tree mutation record,为 oldParent 排队,参数为 « »、« node »、oldPreviousSibling 与 oldNextSibling。
-
Queue a tree mutation record,为 newParent 排队,参数为 « node »、« »、newPreviousSibling 与 child。
要 replace 一个 node child,用一个 node node 在 node parent 中:
-
如果 parent 不是
Document、DocumentFragment或Element, 则 throw 一个 "HierarchyRequestError"DOMException。 -
如果 node 是 parent 的 host-including inclusive ancestor, 则 throw 一个 "
HierarchyRequestError"DOMException。 -
如果 child 的 parent 不是 parent,则 throw 一个 "
NotFoundError"DOMException。 -
如果 node 不是
DocumentFragment、DocumentType、Element或CharacterData类型的 node,则 throw 一个 "HierarchyRequestError"DOMException。 -
如果 node 是
Text节点 且 parent 是 document, 或者 node 是一个 doctype 且 parent 不是 document, 则 throw 一个 "HierarchyRequestError"DOMException。 -
如果 parent 是一个 document,并且下列关于 node 的接口实现(switched on the interface) 中任一条为真,则 throw 一个 "
HierarchyRequestError"DOMException。DocumentFragment-
如果 node 有多于一个的 element 子节点,或有一个
Text子节点。否则,如果 node 有一个 element 子节点,且同时 parent 有一个不是 child 的 element 子节点,或有一个 doctype 位于 child 之后。
Element-
如果 parent 有一个不是 child 的 element 子节点,或有一个 doctype 位于 child 之后。
DocumentType-
如果 parent 有一个不是 child 的 doctype 子节点,或有一个 element 位于 child 之前。
上述判断与 pre-insert 算法不同。
-
令 referenceChild 为 child 的 next sibling。
-
如果 referenceChild 是 node,则将 referenceChild 设为 node 的 next sibling。
-
令 previousSibling 为 child 的 previous sibling。
-
令 removedNodes 为空集合。
-
如果 child 的 parent 非空:
-
将 removedNodes 设为 « child »。
-
Remove child,并将 suppressObservers 设为 true。
上述情况只有在 child 为 node 时才为假。
-
-
令 nodes 为:如果 node 是一个
DocumentFragment节点, 则为其 children;否则为 « node »。 -
Insert node 到 parent 的 referenceChild 之前,并将 suppressObservers 设为 true。
-
Queue a tree mutation record,为 parent 排队,参数为 nodes、removedNodes、previousSibling 与 referenceChild。
-
返回 child。
要在节点或null node内,对节点 parent替换全部:
-
令 removedNodes 为 parent 的 children。
-
令 addedNodes 为空集。
-
如果 node 是一个
DocumentFragment节点,则将 addedNodes 设为 node 的 children。 -
否则,如果 node 非空,则将 addedNodes 设为 « node »。
-
Remove parent 的全部 children,按 tree order,并将 suppressObservers 设为 true。
-
如果 node 非空,则以 insert 将 node 插入到 parent 的 null 之前,并将 suppressObservers 设为 true。
-
如果 addedNodes 或 removedNodes 中任一者 非空,则为 parent 排队一个 tree mutation record,参数为 addedNodes、removedNodes、null 和 null。
该算法不会对 node tree 约束进行任何检查。规范作者需谨慎使用。
要从一个 node parent 中 pre-remove 一个 node child:
-
如果 child 的 parent 不是 parent,则 throw 一个 "
NotFoundError"DOMException。 -
Remove child。
-
返回 child。
相关规范 可能为所有或部分 nodes 定义 removing steps。 该算法接收一个 node removedNode 与一个可为 null 的 node-or-null oldParent,如下面 remove 算法所示。
要 remove 一个 node node,可选地带有布尔型 suppressObservers (默认 false):
-
令 parent 为 node 的 parent。
-
断言:parent 非空。
-
运行 live range pre-remove steps,参数为 node。
-
对于每个其 NodeIterator 对象 iterator,其 root 的 node document 为 node 的 node document:运行 NodeIterator pre-remove steps, 参数为 node 与 iterator。
-
令 oldPreviousSibling 为 node 的 previous sibling。
-
令 oldNextSibling 为 node 的 next sibling。
-
如果 node 是 assigned,则为其 assigned slot 运行 assign slottables。
-
如果 parent 的 root 是 shadow root,且 parent 是一个 slot 且其 assigned nodes 为空表, 则对 parent 运行 signal a slot change。
-
如果 node 有一个作为 inclusive descendant 的 slot:
-
运行 assign slottables for a tree,参数为 parent 的 root。
-
运行 assign slottables for a tree,参数为 node。
-
-
运行 removing steps,参数为 node 与 parent。
-
令 isParentConnected 为 parent 的 connected。
-
如果 node 是 custom 且 isParentConnected 为 true, 则以 node、回调名 "
disconnectedCallback" 及 « » 入队一个自定义元素回调反应。 -
对于 node 的每个 shadow-including descendant descendant,按 shadow-including tree order:
-
对 descendant 运行 removing steps,参数为 descendant 与 null。
-
如果 descendant 是 custom 且 isParentConnected 为 true, 则以 descendant、回调名 "
disconnectedCallback" 及 « » 入队一个自定义元素回调反应。
-
-
对于 parent 的每个 inclusive ancestor inclusiveAncestor,然后对其 registered observer list 中的每个 registered:如果 registered 的 options["
subtree"] 为 true,则追加一个新的 transient registered observer,其 observer 为 registered 的 observer,其 options 为 registered 的 options,且其 source 为指向 node 的 registered observer list 的 registered。 -
如果 suppressObservers 为 false,则为 parent 排队一个 tree mutation record,参数为 « »、« node »、 oldPreviousSibling 与 oldNextSibling。
-
为 parent 运行 children changed steps。
4.2.4. 混入 NonElementParentNode
出于 Web 兼容性的考虑,阻止 getElementById() 方法在 elements 上被暴露(因此也不会在 ParentNode 上暴露)。
interface mixin {NonElementParentNode Element ?getElementById (DOMString ); };elementId Document includes NonElementParentNode ;DocumentFragment includes NonElementParentNode ;
The getElementById(elementId) 方法的步骤是返回在 树顺序(tree order) 中、位于 this 的 后代(descendants) 中的第一个 元素(element),且该元素的 ID 为 elementId;否则,如果不存在这样的 元素(element),则返回 null。
4.2.5. Mixin 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. Mixin ParentNode
要将节点转换为单个节点,给定 nodes 和 document,请执行以下步骤:
-
令 node 为 null。
-
将 nodes 中的每个字符串替换为一个新的
Textnode,其 data 为该字符串, 且 node document 为 document。 -
如果 nodes 包含一个 node,则将 node 设为 nodes[0]。
-
否则,将 node 设为一个新的
DocumentFragmentnode,其 node document 为 document,然后将 nodes 中的每个(如有)node 附加到该节点上。 -
返回 node。
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- 返回作为子项的child类型的element元素。
element = node .firstElementChild- 返回第一个作为子项的child且为element的节点;否则返回 null。
element = node .lastElementChild- 返回最后一个作为子项的child且为element的节点;否则返回 null。
node . prepend(nodes)-
在 node 的第一个first child 之前插入 nodes,同时将 nodes 中的字符串替换为等价的
Text类型的nodes。抛出一个 "
HierarchyRequestError"DOMException,如果违反了node tree 的约束。 node . append(nodes)-
在 node 的最后一个last child 之后插入 nodes,同时将 nodes 中的字符串替换为等价的
Text类型的nodes。抛出一个 "
HierarchyRequestError"DOMException,如果违反了node tree 的约束。 node . replaceChildren(nodes)-
用 nodes 替换 node 的所有children,同时将 nodes 中的字符串替换为等价的
Text类型的nodes。抛出一个 "
HierarchyRequestError"DOMException,如果违反了node tree 的约束。 node . moveBefore(movedNode, child)-
将 movedNode 移动到 node 内,若 child 非空则放在 child 之后;否则放在 node 的最后一个last child 之后。此方法在移动时保留与 movedNode 关联的状态。
抛出一个 "
HierarchyRequestError"DOMException,如果违反了node tree 的约束,或无法保留与被移动节点关联的状态。 node . querySelector(selectors)-
返回第一个作为 node 的descendant且匹配 selectors 的element。
node . querySelectorAll(selectors)-
返回所有作为 node 的descendants且匹配 selectors 的element。
children 获取器的步骤是返回一个 HTMLCollection collection,其以 this 为根, 并且仅匹配 element children。
firstElementChild 获取器的步骤是返回第一个作为 child 且为 element 的节点;否则返回 null。
lastElementChild 获取器的步骤是返回最后一个作为 child 且为 element 的节点;否则返回 null。
childElementCount 获取器的步骤是返回 this 的 children 中作为 elements 的数量。
prepend(nodes) 方法的步骤如下:
append(nodes) 方法的步骤是:
-
设 node 为给定 nodes 和此对象的节点文档,将节点转换为单个节点的结果。
replaceChildren(nodes) 方法的步骤是:
-
设 node 为给定 nodes 和此对象的节点文档,将节点转换为单个节点的结果。
-
在 null 之前,确保将 node 预插入到此对象的有效性。
moveBefore(node, child) 方法的步骤是:
-
设 referenceChild 为 child。
-
如果 referenceChild 是 node,则将 referenceChild 设置为 node 的下一个兄弟节点。
querySelector(selectors) 方法的步骤是:如果结果不是空列表,则返回对此对象运行作用域匹配选择器字符串 selectors 的第一个结果;否则返回 null。
querySelectorAll(selectors) 方法的步骤是返回对此对象运行作用域匹配选择器字符串 selectors 的静态结果。
4.2.7. 混入 NonDocumentTypeChildNode
Web 兼容性阻止了 previousElementSibling 和 nextElementSibling 特性在文档类型上公开(因此也在 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。
previousElementSibling getter 的步骤是返回作为元素的第一个前置兄弟节点;否则返回 null。
nextElementSibling getter 的步骤是返回作为元素的第一个后续兄弟节点;否则返回 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 中的字符串替换为等价的
Textnodes。抛出一个 "
HierarchyRequestError"DOMException,如果违反了node tree 的约束。 node .after(...nodes)-
将 nodes 插入到 node 之后,同时将 nodes 中的字符串替换为等价的
Textnodes。抛出一个 "
HierarchyRequestError"DOMException,如果违反了node tree 的约束。 node .replaceWith(...nodes)-
用 nodes 替换 node,同时将 nodes 中的字符串替换为等价的
Textnodes。抛出一个 "
HierarchyRequestError"DOMException,如果违反了node tree 的约束。 node .remove()- 移除 node。
before(nodes) 方法的步骤为:
-
如果 parent 为 null,则返回。
-
设 node 为给定 nodes 和此对象的节点文档,将节点转换为单个节点的结果。
-
如果 viablePreviousSibling 为 null,则将其设置为 parent 的第一个子节点;否则将其设置为 viablePreviousSibling 的下一个兄弟节点。
-
在 viablePreviousSibling 之前,将 node 预插入到 parent 中。
after(nodes) 方法的步骤为:
-
如果 parent 为 null,则返回。
-
设 node 为给定 nodes 和此对象的节点文档,将节点转换为单个节点的结果。
-
在 viableNextSibling 之前,将 node 预插入到 parent 中。
replaceWith(nodes) 方法的步骤是:
-
如果 parent 为 null,则返回。
-
设 node 为给定 nodes 和此对象的节点文档,将节点转换为单个节点的结果。
-
如果此对象的父节点是 parent,则在 parent 中用 node 替换此对象。
此对象可能已被插入到 node 中。
-
否则,在 viableNextSibling 之前,将 node 预插入到 parent 中。
remove() 方法的步骤是:
4.2.9. 混入 Slottable
interface mixin {Slottable readonly attribute HTMLSlotElement ?assignedSlot ; };Element includes Slottable ;Text includes Slottable ;
assignedSlot getter 的步骤是返回给定此对象和 true 的查找插槽的结果。
4.2.10. 旧式集合:NodeList 和 HTMLCollection
集合是一个表示节点列表的对象。一个集合可以是动态的,也可以是静态的。除非另有说明,否则集合必须是动态的。
如果集合是实时集合,那么该对象上的属性和方法必须操作实际的底层数据,而不是数据的快照。
当集合创建时,会与其关联一个过滤器和根。
然后,集合 表示以集合的根为根的子树的视图,仅包含符合给定过滤器的节点。该视图是线性的。在没有特定要求的情况下,集合中的节点必须按树顺序排序。
4.2.10.1. 接口 NodeList
[Exposed =Window ]interface {NodeList getter Node ?item (unsigned long );index readonly attribute unsigned long length ;iterable <Node >; };
- collection .
length - 返回此 collection 中 nodes 的数量。
- element = collection .
item(index)- element = collection[index]
- 返回来自该 collection、索引为 index 的 node。这些 nodes 按照 tree order 进行排序。
该对象的 supported property indices 是从 0 到表示该集合的节点数减一的数字范围。如果没有这样的元素,则不存在任何 supported property indices。
length 属性必须返回该集合所表示的节点数, 即 represented by the collection 的数量。
item(index) 方法必须返回集合中第 indexth 个 node。如果集合中不存在第 indexth 个 node,则该方法必须返回 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]
- 从集合中返回ID 或名称为 name 的第一个元素。
对象的支持的属性索引是从零到元素数量减一的范围内的数字由集合表示。如果没有这样的元素,那么就没有支持的属性索引。
length获取器步骤应返回由集合表示的节点数量。
item(index) 方法的步骤是:返回集合中的第 index 个元素。如果集合中没有第 index 个元素,则该方法必须返回 null。
支持的属性名称是通过以下步骤返回的列表中的值:
-
令result为一个空列表。
-
返回result。
namedItem(key)方法步骤是:
-
如果 key 是空字符串,则返回 null。
-
如果没有这样的元素,则返回 null。
4.3. Mutation observers
每个相同来源窗口代理都有一个突变观察者微任务排队(布尔值),其初始值为false。[HTML]
每个相同来源窗口代理还具有待处理的突变观察者(一个包含零个或多个MutationObserver对象的集合),其初始状态为空。
要排队一个突变观察者微任务,请执行以下步骤:
-
如果周围代理的突变观察者微任务排队为true,则返回。
-
将周围代理的突变观察者微任务排队设置为true。
要通知突变观察者,请执行以下步骤:
-
将周围代理的突变观察者微任务排队设置为false。
-
对于notifySet中的每个mo:
-
对于 signalSet 中的每个 slot: 在 slot 上触发一个名为
slotchange的事件,并将其bubbles属性设置为 true。
每个节点都有一个注册观察者列表(一个包含零个或多个注册观察者的列表),初始为空。
一个注册观察者由一个观察者(一个MutationObserver对象)和选项(一个MutationObserverInit字典)组成。
一个瞬态注册观察者是一个注册观察者,它还包括一个源(一个注册观察者)。
瞬时注册观察者 用于在给定的 node 被移除之后,跟踪其 后代 中的变更,以便在对 node 的 parent 将 subtree 设置为 true 时,这些变更不会丢失。
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
A MutationObserver 对象可用于观察节点树的变更。
每个 MutationObserver 对象具有以下相关概念:
- 在创建时设置的 callback。
- 一个 node list(一个对list 的弱引用,包含 nodes),初始为空。
- 一个 record queue(一个 queue,包含零个或多个
MutationRecord对象),初始为空。
observer = newMutationObserver(callback)- 构造一个
MutationObserver对象,并将其 callback 设置为 callback。当通过MutationRecord对象列表作为第一个参数并且构造的MutationObserver对象作为第二个参数调用时,即在使用observe()方法注册的 nodes 发生变更之后,callback 会被调用。 observer .observe(target, options)- 指示用户代理观察给定的 target(一个node) 并根据 options(一个对象)提供的条件报告任何变更。
options 参数允许通过对象成员设置变更观察选项。可以使用的对象成员如下:
childList- 如果要观察 target 的子节点(children)的变更,则设置为 true。
attributes- 如果要观察 target 的属性的变更,则设置为 true。 如果同时指定了
attributeOldValue或attributeFilter则可以省略此项。 characterData- 如果要观察 target 的data 的变更,则设置为 true。 如果同时指定了
characterDataOldValue则可以省略此项。 subtree- 如果要观察的不仅是 target 本身,而且还包括 target 的后代 的变更,则设置为 true。
attributeOldValue- 如果在变更前需要记录 target 的attribute 的value,并且
attributes为 true 或被省略,则设置为 true。 characterDataOldValue- 如果在变更前需要记录 target 的data,并且
characterData被设置为 true 或被省略,则设置为 true。 attributeFilter- 如果不需要观察所有的属性变更, 且
attributes为 true 或被省略,则将其设置为一个包含属性本地名(不含命名空间)的列表。
observer .disconnect()- 停止 observer 对任何变更的观察。在再次使用
observe()方法之前,observer 的 callback 不会被调用。 observer .takeRecords()- 清空 record queue 并返回其中的内容。
The new MutationObserver(callback) 构造函数步骤是将 this 的 callback 设置为 callback。
The observe(target, options) 方法步骤如下:
-
如果 options["
attributeOldValue"] 或 options["attributeFilter"] 存在(exists),且 options["attributes"] 不存在(不 exist),则将 options["attributes"] 设为 true。 -
如果 options["
characterDataOldValue"] 存在(exists)且 options["characterData"] 不存在(不 exist),则将 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。 -
对于每个 属于 target 的 registered observer list 的 registered:如果 registered 的 observer 是 this:
-
对于每个 属于 this 的 node list 的 node:移除 该 node 的 registered observer list 中所有来源(source)为 registered 的 transient registered observers。
-
将 registered 的 options 设置为 options。
-
-
否则:
-
追加 一个新的 registered observer 到 target 的 registered observer list,其 observer 为 this,其 options 为 options。
-
The disconnect() 方法步骤如下:
-
对于每个 属于 this 的 node list 的 node:移除 该 node 的 registered observer list 中所有其 this 为 observer 的 registered observer。
-
清空 this 的 record queue。
The takeRecords() 方法步骤如下:
-
令 records 为 clone 的 this 的 record queue。
-
清空 this 的 record queue。
-
返回 records。
4.3.2. 排队突变记录
要入队 mutation 记录 (queue a mutation record),类型为 type,目标为 target,并带有 name、namespace、oldValue、addedNodes、removedNodes、previousSibling 和 nextSibling,请执行以下步骤:
-
设 interestedObservers 为一个空的有序映射。
-
设 nodes 为 target 的包含祖先。
-
对于 nodes 中的每个 node,然后 对于每个 registered 位于 node 的 已注册的观察者列表:
-
设 options 为 registered 的选项。
-
如果以下条件均不为真:
- node 不是 target 且 options["
subtree"] 为 false - type 是 "
attributes" 且 options["attributes"] 或者不存在或者为 false - type 是 "
attributes",options["attributeFilter"] 存在,并且 options["attributeFilter"] 不包含 name 或者 namespace 非空 - 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 中的每个 observer → mappedOldValue:
-
设 record 为一个新的
MutationRecord对象,其type设为 type,target设为 target,attributeName设为 name,attributeNamespace设为 namespace,oldValue设为 mappedOldValue,addedNodes设为 addedNodes,removedNodes设为 removedNodes,previousSibling设为 previousSibling,且nextSibling设为 nextSibling。
-
要入队树结构变更记录 (queue a tree mutation record),目标为 target,并带有 addedNodes、removedNodes、previousSibling 和 nextSibling,请执行以下步骤:
-
断言:addedNodes 或 removedNodes 不为空。
-
为 target 将一个 "
childList" 类型的突变记录排队,附带 null、null、null、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- 如果是对某个attribute 的变更,则返回 "
attributes"。 如果是对一个CharacterDatanode 的变更,则返回 "characterData"。如果是对nodes 的树的变更,则返回 "childList"。 record .target- 根据
type的值,返回该次变更影响的 node。 对于 "attributes",返回其属性发生改变的 element。 对于 "characterData",返回该CharacterDatanode。对于 "childList",返回其子节点发生变化的 node。 record .addedNodesrecord .removedNodes- 分别返回被添加和被移除的 nodes。
record .previousSiblingrecord .nextSibling- 分别返回被添加或移除的 nodes 的前一个兄弟节点和下一个兄弟节点(即previous 与 next sibling);否则为 null。
record .attributeName- 返回被更改的 attribute 的本地名(local name);否则为 null。
record .attributeNamespace- 返回被更改的 attribute 的命名空间(namespace);否则为 null。
record .oldValue- 返回值取决于
type。 对于 "attributes",返回变更发生前该被更改的 attribute 的 value。 对于 "characterData",返回变更发生前该被更改 node 的 data。 对于 "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 是一个抽象接口, 被所有节点使用。你无法获取它的直接实例。
每个节点都有一个关联的 node document,在创建时设置,该关联对象是一个 文档。
一个节点的node document可以被采纳(adopt)算法更改。
一个节点的get the parent算法, 在给定event的情况下,会返回该节点的assigned slot(如果该节点被assigned);否则返回该节点的parent。
每个节点还拥有一个registered observer list。
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 getter 的步骤是返回第一个匹配的语句,具体取决于此对象实现的接口:
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 getter 的步骤是返回第一个匹配的语句,具体取决于此对象实现的接口:
Element- 其HTML 大写限定名。
Attr- 其限定名。
- 一个排他的
Text节点 - "
#text"。 CDATASection- "
#cdata-section"。 ProcessingInstruction- 其目标。
Comment- "
#comment"。 Document- "
#document"。 DocumentType- 其名称。
DocumentFragment- "
#document-fragment"。
node .baseURI- 返回 node 的节点文档的文档基本 URL。
baseURI getter 的步骤是返回此对象的节点文档的文档基本 URL,并进行序列化。
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 getter 的步骤是:如果此对象是已连接的,则返回 true;否则返回 false。
ownerDocument getter 的步骤是:如果此对象是一个文档,则返回 null;否则返回此对象的节点文档。
一个文档的节点文档就是该文档本身。所有节点始终都有一个节点文档。
getRootNode(options) 方法的步骤是:如果 options["composed"] 为 true,则返回此对象的包含阴影的根节点;否则返回此对象的根节点。
parentNode getter 的步骤是返回此对象的父节点。
parentElement getter 的步骤是返回此对象的父元素。
hasChildNodes() 方法的步骤是:如果此对象有子节点,则返回 true;否则返回 false。
childNodes getter 的步骤是返回一个以此对象为根且仅匹配子节点的 NodeList。
firstChild getter 的步骤是返回此对象的第一个子节点。
lastChild getter 的步骤是返回此对象的最后一个子节点。
previousSibling getter 的步骤是返回此对象的前一个兄弟节点。
nextSibling getter 的步骤是返回此对象的下一个兄弟节点。
nodeValue getter 的步骤是返回以下内容,具体取决于此对象实现的接口:
Attr- 此对象的值。
CharacterData- 此对象的数据。
- 其他情况
- Null。
nodeValue setter 的步骤是,如果给定值为 null,则视为空字符串,然后执行以下描述的操作,具体取决于此对象实现的接口:
使用节点 node 获取文本内容的步骤是返回以下内容,具体取决于 node 实现的接口:
DocumentFragmentElement- node 的后代文本内容。
Attr- node 的值。
CharacterData- node 的数据。
- 其他情况
- Null。
The textContent getter 步骤为:返回运行 获取文本内容 并以 this 作为参数的结果。
要在一个 node parent 内对字符串 string 执行 string replace all,请运行下列步骤:
-
令 node 为 null。
-
如果 string 不是空字符串,则将 node 设为一个新的
Textnode,其 data 为 string,且其 node document 为 parent 的 node document。 -
替换全部:在 parent 内用 node 替换全部内容。
要使用一个 node node 和一个字符串 value 来 设置文本内容,按下述定义执行,基于 node 实现的接口(switch on the interface node implements)进行分支:
DocumentFragmentElement-
对字符串执行全部替换:在 node 内用 value 替换全部。
Attr-
调用 设置已有属性值,参数为 node 与 value。
CharacterData- Otherwise
-
不执行任何操作。
The textContent setter 的步骤是:如果给定的值为 null,则将其视为一个空字符串,然后用 设置文本内容 算法,以 this 和该给定值作为参数运行。
node .normalize()- 移除空的 empty 独占的
Text节点,并将剩余的相邻 连续的独占Text节点 的 data 串联到它们中第一个节点上。
The normalize() 方法的步骤是:对 每个后代 中作为 独占 Text 节点 的 node(以 this 为起点)运行如下步骤:
- 令 length 为 node 的 length。
- 如果 length 为零,则 移除 node,并继续处理下一个(如有)独占
Text节点。 - 令 data 为将 node 的 连续的独占
Text节点(不包括自身) 的 data 按照 串联(以树序为顺序)得到的结果。 - 调用 替换数据:节点为 node,偏移量为 length,计数为 0,数据为 data。
- 令 currentNode 为 node 的 下一个兄弟节点。
-
当 currentNode 是一个 独占
Text节点 时,执行下列循环体:-
对于每个 live range,其 start node 为 currentNode:将 length 加到其 start offset 并将其 start node 设为 node。
-
对于每个 live range,其 end node 为 currentNode:将 length 加到其 end offset 并将其 end node 设为 node。
-
对于每个 live range,其 start node 为 currentNode 的 parent,且 start offset 为 currentNode 的 index:将其 start node 设为 node,并将其 start offset 设为 length。
-
对于每个 live range,其 end node 为 currentNode 的 parent,且 end offset 为 currentNode 的 index:将其 end node 设为 node,并将其 end offset 设为 length。
-
将 currentNode 的 length 加到 length。
-
将 currentNode 设为其 next sibling。
-
- 移除 node 的 连续的独占
Text节点(不包括自身),按 树序 顺序移除。
node . cloneNode([subtree = false])- 返回 node 的副本。如果 subtree 为 true,则该副本还包括 node 的 后代。
node .isEqualNode(otherNode)- 返回 node 与 otherNode 是否具有相同属性的布尔值。
HTML 为若干元素定义了 克隆步骤,例如 input、 script 与 template。SVG 本应对其 script 元素也这样做,但目前未实现。
要 克隆一个节点,给定一个 node node 以及一个可选的 document document(默认为 node 的 node document)、布尔值 subtree(默认为 false)、node-或-null 的 parent(默认为 null),以及可为 null 的 CustomElementRegistry 对象 fallbackRegistry (默认为 null):
-
令 copy 为执行 克隆单个节点(参数为 node、document 与 fallbackRegistry) 的结果。
-
对 node 在 其他适用规范 中定义的任何 克隆步骤 运行一遍,并将 node、copy 与 subtree 作为参数传入。
-
如果 parent 非空,则将 copy 附加 到 parent。
-
如果 subtree 为 true,则对于 node 的每个 child(按 children 中的顺序),按 树序 执行:以 child 为参数调用 克隆节点,并将 document 设置为 document,subtree 设置为 subtree,parent 设置为 copy,以及 fallbackRegistry 设置为 fallbackRegistry。
-
如果 node 是一个 element,且 node 是一个 shadow host,并且 node 的 shadow root 的 clonable 为 true,则执行下列步骤:
-
断言:copy 不是一个 shadow host。
-
令 shadowRootRegistry 为 node 的 shadow root 的 custom element registry。
-
如果 shadowRootRegistry 是全局 custom element registry,则将 shadowRootRegistry 设为 document 的 有效的全局 custom element registry。
-
用 copy、node 的 shadow root 的 mode、true、node 的 shadow root 的 serializable、node 的 shadow root 的 delegates focus、node 的 shadow root 的 slot assignment 以及 shadowRootRegistry 调用 Attach a shadow root。
-
将 copy 的 shadow root 的 declarative 设置为 node 的相应值。
-
对于 node 的 shadow root 的每个子节点 child(按其 children 的树序): 调用 克隆节点,参数为 child,并将 document 设为 document、subtree 设为 subtree,以及将 parent 设为 copy 的 shadow root。
此处刻意不传递 fallbackRegistry 参数。
-
-
返回 copy。
要 克隆单个节点,给定一个 node node、document document,以及可为 null 的 CustomElementRegistry 对象 fallbackRegistry 时,执行下列步骤:
-
令 copy 为 null。
-
如果 node 是一个 element:
-
令 registry 为 node 的 custom element registry。
-
如果 registry 为 null,则将其设为 fallbackRegistry。
-
如果 registry 是一个 全局 custom element registry,则将其设为 document 的 有效的全局 custom element registry。
-
令 copy 为调用 创建元素 的结果,参数为 document、node 的 local name、node 的 namespace、node 的 namespace prefix、node 的
isvalue、false 与 registry。 -
对于 node 的每个 attribute(遍历其 attribute list):
-
-
否则,将 copy 设为一个实现与 node 相同接口的 node,并满足下列附加要求,基于 node 实现的接口(switch)进行分支:
Document-
-
将 copy 的 encoding、content type、URL、origin、type、mode,以及 allow declarative shadow roots 设置为与 node 相同的值。
-
如果 node 的 custom element registry 的 is scoped 为 true,则将 copy 的相应 custom element registry 设为 node 的那个 registry。
-
DocumentTypeAttr-
将 copy 的 namespace、namespace prefix、local name 以及 value 设为与 node 相同的值。
TextComment-
将 copy 的 data 设为与 node 相同的值。
ProcessingInstruction- Otherwise
-
不执行任何操作。
-
如果 node 是一个 document,则将 document 设为 copy。
-
将 copy 的 node document 设为 document。
-
返回 copy。
cloneNode(subtree) 方法的步骤为:
-
如果 this 是一个 shadow root,则 抛出 一个 "
NotSupportedError"DOMException。
若节点 A 与节点 B 满足下列所有条件,则称 A equals B:
-
A 与 B 实现 相同的接口。
-
基于 A 实现的接口(switch),下列项相等:
DocumentType- 其 name、public ID 以及 system ID。
Element- 其 namespace、namespace prefix、local name,以及其属性列表(size)。
Attr- 其 namespace、local name 以及 value。
ProcessingInstruction- 其 target 與 data。
TextComment- 其 data。
- Otherwise
- —
-
如果 A 是一个 element,则其 属性列表 中的每个 attribute 都有一个在 B 的属性列表中与之 equals 的对应 attribute。
-
A 与 B 的子节点数量相同。
-
A 的每个子节点在相同的索引位置上都与 B 的对应子节点 equals。
isEqualNode(otherNode) 方法的步骤为:如果 otherNode 非空且 this 与 otherNode 满足 equals,则返回 true;否则返回 false。
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, 16 的十六进制表示为 10);DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC(32, 32 的十六进制表示为 20)。
方法compareDocumentPosition(other)的步骤如下:
-
如果 this 是 other,则返回零。
-
令 node1 为 other,令 node2 为 this。
-
令 attr1 与 attr2 为 null。
-
如果 node1 是一个 attribute,则将 attr1 设为 node1,并将 node1 设为 attr1 的 element。
-
如果 node2 是一个 attribute:
-
将 attr2 设为 node2,并将 node2 设为 attr2 的 element。
-
如果 attr1 与 node1 非空,且 node2 为 node1:
-
对于 node2 的 attribute list 中的每个 attr:
-
如果 attr equals attr1,则返回将
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC与DOCUMENT_POSITION_PRECEDING相加的结果。 -
如果 attr equals attr2,则返回将
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC与DOCUMENT_POSITION_FOLLOWING相加的结果。
-
-
-
-
如果 node1 或 node2 为 null,或 node1 的 root 不是 node2 的 root,则返回将
DOCUMENT_POSITION_DISCONNECTED、DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC与DOCUMENT_POSITION_PRECEDING或DOCUMENT_POSITION_FOLLOWING(二者之一)相加的结果,并且附带这些值须保持一致的约束。通常通过指针比较来决定返回
DOCUMENT_POSITION_PRECEDING还是DOCUMENT_POSITION_FOLLOWING。在 JavaScript 实现中,可以使用缓存的Math值来实现。. random() -
如果 node1 是 node2 的 ancestor 且 attr1 为 null,或 node1 与 node2 相同且 attr2 非空,则返回将
DOCUMENT_POSITION_CONTAINS与DOCUMENT_POSITION_PRECEDING相加的结果。 -
如果 node1 是 node2 的 descendant 且 attr2 为 null,或 node1 与 node2 相同且 attr1 非空,则返回将
DOCUMENT_POSITION_CONTAINED_BY与DOCUMENT_POSITION_FOLLOWING相加的结果。 -
如果 node1 在树序上 preceding node2,则返回
DOCUMENT_POSITION_PRECEDING。由于此算法处理 attributes 的方式,这会导致某个 节点 的 attributes 被计算为位于该 节点 的 子节点 之前,尽管这些 attributes 并不参与同一棵 树。
contains(other) 方法的步骤是:如果 other 是此对象的包含后代,则返回 true;否则返回 false(包括当 other 为 null 时)。
要为一个使用namespace的element 定位命名空间前缀,请执行以下步骤:
要为一个node使用prefix 定位命名空间,请根据node 实现的接口进行切换:
ElementDocumentDocumentTypeDocumentFragment-
返回 null。
Attr- 否则
方法lookupPrefix(namespace)的步骤如下:
-
如果 namespace 为 null 或空字符串,则返回 null。
方法lookupNamespaceURI(prefix)的步骤如下:
方法isDefaultNamespace(namespace)的步骤如下:
-
如果 namespace 是空字符串,则将其设置为 null。
-
如果 defaultNamespace 与 namespace 相同,则返回 true;否则返回 false。
insertBefore(node, child) 方法的步骤是返回将 node 预插入到此对象中 child 之前的结果。
appendChild(node) 方法的步骤是返回将 node 追加到此对象的结果。
replaceChild(node, child) 方法的步骤是返回在此对象内用 node 替换 child 的结果。
removeChild(child) 方法的步骤是返回从此对象中预移除 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",允许声明式 Shadow Roots为 false, 自定义元素注册表为 null。
如果文档的类型是“xml”,则称其为 XML 文档;否则称为 HTML 文档。 文档是 HTML 文档还是 XML 文档会影响某些 API 的行为。
如果文档的模式是“no-quirks”,则称其处于无怪异模式;如果其模式是“quirks”,则称其处于怪异模式;如果其模式是“limited-quirks”,则称其处于有限怪异模式。
模式仅在由 HTML 解析器根据 DOCTYPE 字符串的存在、缺失或值创建的文档以及新的浏览上下文(初始“about:blank”)的情况下才会从默认值更改。[HTML]
无怪异模式最初称为“标准模式”,而有限怪异模式曾称为“准标准模式”。它们已被重命名,因为它们的细节现在由标准定义。(并且因为 Ian Hickson 以它们无意义为由否决了它们最初的名称。)
给定一个event,文档的获取父级算法,如果 event 的 type 属性值为“load”或者文档没有浏览上下文,则返回 null;否则返回文档的相关全局对象。
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() 构造函数的步骤是将此对象的源设置为当前全局对象的关联 Document 的源。[HTML]
与 createDocument() 不同,此构造函数不返回 XMLDocument 对象,而是返回一个文档(Document 对象)。
implementation getter 的步骤是返回与此对象关联的 DOMImplementation 对象。
URL 和 documentURI getter 的步骤是返回此对象的URL(序列化后)。
compatMode getter 的步骤是:如果此对象的模式是“quirks”,则返回“BackCompat”;否则返回“CSS1Compat”。
characterSet、charset 和 inputEncoding getter 的步骤是返回此对象的编码的名称。
contentType getter 的步骤是返回此对象的内容类型。
- document .
doctype - 返回 doctype,如果没有则返回 null。
- document .
documentElement - 返回 document element。
collection = document . getElementsByTagName(qualifiedName)-
如果 qualifiedName 为 "
*",则返回一个包含所有后代 descendant elements 的HTMLCollection。否则,返回一个
HTMLCollection,其中包含所有后代 descendant elements,这些元素的 qualified name 为 qualifiedName。 (在 HTML namespace 中的元素并且文档是 HTML document 时,匹配时对大小写不敏感。) collection = document . getElementsByTagNameNS(namespace, localName)-
如果 namespace 和 localName 都为 "
*",则返回一个包含所有后代 descendant elements 的HTMLCollection。如果只有 namespace 为 "
*",则返回一个HTMLCollection, 包含所有后代 descendant elements,这些元素的 local name 为 localName。如果只有 localName 为 "
*",则返回一个HTMLCollection, 包含所有后代 descendant elements,这些元素的 namespace 为 namespace。否则,返回一个
HTMLCollection, 包含所有后代 descendant elements,这些元素的 namespace 为 namespace 且其 local name 为 localName。 collection = document . getElementsByClassName(classNames)collection = element . getElementsByClassName(classNames)-
返回一个
HTMLCollection, 包含在调用该方法的对象(一个 document 或一个 element)中具有所有由 classNames 指定的类的 elements。 classNames 参数被解释为以空格分隔的类名列表。
doctype getter 的步骤是返回此对象中作为文档类型的子节点;否则返回 null。
documentElement getter 的步骤是返回此对象的文档元素。
getElementsByTagName(qualifiedName) 方法的步骤是返回此对象的具有限定名 qualifiedName 的元素列表。
因此,在 HTML 文档中,document 将匹配不在HTML 命名空间中的 <FOO> 元素,以及在HTML 命名空间中的 <foo> 元素,但不匹配在HTML 命名空间中的 <FOO> 元素。
getElementsByTagNameNS(namespace, localName) 方法的步骤是返回此对象的具有命名空间 namespace 和本地名称 localName 的元素列表。
getElementsByClassName(classNames) 方法的步骤是返回此对象的具有类名 classNames 的元素列表。
< div id = "example" > < p id = "p1" class = "aaa bbb" /> < p id = "p2" class = "aaa ccc" /> < p id = "p3" class = "bbb ccc" /> </ div > 调用document将返回一个包含两个段落p1和p2的HTMLCollection。
调用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。如果以下任一条件为真,则会抛出“
NamespaceError”DOMException:- 命名空间前缀不为 null 且 namespace 为空字符串。
- 命名空间前缀为“
xml”且 namespace 不是XML 命名空间。 - qualifiedName 或命名空间前缀为“
xmlns”且 namespace 不是XMLNS 命名空间。 - namespace 是XMLNS 命名空间且 qualifiedName 和命名空间前缀都不是“
xmlns”。
当同时提供 options 的
customElementRegistry和 options 的is时, 将抛出“NotSupportedError”DOMException。 documentFragment = document .createDocumentFragment()- 返回一个
DocumentFragmentnode. text = document .createTextNode(data)- 返回一个
Textnode,其 data 为 data。 text = document .createCDATASection(data)- 返回一个
CDATASectionnode,其 data 为 data。 comment = document .createComment(data)- 返回一个
Commentnode,其 data 为 data。 processingInstruction = document .createProcessingInstruction(target, data)- 返回一个
ProcessingInstructionnode,其 target 为 target,且 data 为 data。 如果 target 不匹配Name产生式,则会抛出一个 "InvalidCharacterError"DOMException。 如果 data 包含 "?>",则会抛出一个 "InvalidCharacterError"DOMException。
任何 name 和 namespace 的元素接口都是 Element,除非另有说明。
例如,HTML 标准将定义对于 html 和HTML 命名空间,使用 HTMLHtmlElement 接口。[HTML]
createElement(localName, options) 方法的步骤如下:
内部 createElementNS 步骤,给定 document、namespace、qualifiedName 和 options,如下所示:
createElementNS(namespace, qualifiedName, options) 方法的步骤是返回运行内部 createElementNS 步骤的结果,给定此对象、namespace、qualifiedName 和 options。
要展平元素创建选项,给定一个字符串或 ElementCreationOptions 字典 options 和一个 document 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。
createElement() 和 createElementNS() 的 options 参数允许为字符串,以保证网页兼容性。
createDocumentFragment() 方法的步骤是返回一个新的 DocumentFragment 节点,其节点文档是此对象。
createTextNode(data) 方法的步骤是返回一个新的 Text 节点,其数据为 data,节点文档为此对象。
createCDATASection(data) 方法的步骤如下:
-
如果 this 是一个 HTML 文档, 则 抛出 "
NotSupportedError"DOMException。 -
如果 data 包含字符串 "
]]>",则 抛出 "InvalidCharacterError"DOMException。 -
返回一个新的
CDATASection节点,其 data 设置为 data,节点文档 设置为 this。
createComment(data) 方法的步骤是返回一个新的 Comment 节点,其数据为 data,节点文档为此对象。
createProcessingInstruction(target, data) 方法的步骤如下:
- 如果 target 不符合
Name产生式, 则 抛出一个 "InvalidCharacterError"DOMException。 - 如果 data 包含字符串 "
?>",则 抛出一个 "InvalidCharacterError"DOMException。 - 返回一个新的
ProcessingInstruction节点,其中 target 设置为 target, data 设置为 data, 节点文档 设置为 this。
- clone = document . importNode(node [, options = false])
-
返回 node 的一个副本。如果 options 为 true 或 options 是一个字典且其
selfOnly为 false,则副本还包括 node 的 后代。options 的
customElementRegistry可以用于为没有注册表的元素设置CustomElementRegistry。如果 node 是 document 或 shadow root,则会抛出 "
NotSupportedError"DOMException。 - node = document .
adoptNode(node) - 将 node 从另一个 document 移动过来,并返回它。
如果 node 是 document,则抛出 "
NotSupportedError"DOMException,或者如果 node 是 shadow root,则抛出 "HierarchyRequestError"DOMException。
importNode(node, options) 方法步骤如下:
-
如果 node 是 document 或 shadow root,则 抛出 "
NotSupportedError"DOMException。 -
令 subtree 为 false。
-
令 registry 为 null。
-
如果 options 是布尔值,则将 subtree 设置为 options。
-
否则:
-
将 subtree 设置为 options["
selfOnly"] 的非值。 -
如果 options["
customElementRegistry"] 存在,则将 registry 设置为它。 -
如果 registry 的 is scoped 为 false 且 registry 不是 this 的 custom element registry,则 抛出 "
NotSupportedError"DOMException。
-
-
如果 registry 为 null,则将 registry 设置为 查找自定义元素注册表 ,参数为 this。
-
返回 克隆节点的结果,参数为 node, document 设为 this, subtree 设为 subtree, fallbackRegistry 设为 registry。
-
令 oldDocument 为 node 的 节点文档。
-
如果 document 不等于 oldDocument:
-
对 node 的每一个 包含 shadow 的所有后代(inclusiveDescendant),按 包含 shadow 的树顺序遍历:
-
将 inclusiveDescendant 的 节点文档 设为 document。
-
如果 inclusiveDescendant 是 shadow root 并且下面任一为真:
-
inclusiveDescendant 的 自定义元素注册表 为 null, 且 inclusiveDescendant 的 keep custom element registry null 为 false;或
-
inclusiveDescendant 的 自定义元素注册表 为全局自定义元素注册表,
则将 inclusiveDescendant 的 自定义元素注册表 设为 document 的 有效的全局自定义元素注册表。
-
-
否则,如果 inclusiveDescendant 是 元素:
-
-
对 node 的每一个 包含 shadow 的所有后代,如果是 自定义元素,按 包含 shadow 的树顺序遍历: 使用 自定义元素回调反应排队, 参数为 inclusiveDescendant,回调名 "
adoptedCallback",以及 « oldDocument, document »。 -
对 node 的每一个 包含 shadow 的所有后代,按 包含 shadow 的树顺序遍历: 用 收养扩展步骤 处理 inclusiveDescendant 和 oldDocument。
-
adoptNode(node) 方法的步骤如下:
-
如果 node 是一个 document,则抛出 "
NotSupportedError"DOMException。 -
如果 node 是 shadow root,则抛出 "
HierarchyRequestError"DOMException。 -
如果 node 是一个
DocumentFragment节点,并且 host 不为 null,则返回。 -
返回 node。
null 或 CustomElementRegistry 对象 registry 当 registry 不为 null 且 registry 的 is scoped 为 false 时, 被认为是全局自定义元素注册表。
document document 的 有效的全局自定义元素注册表 如下:
-
如果 document 的 自定义元素注册表 为全局自定义元素注册表,则返回 document 的 自定义元素注册表。
-
返回 null。
createAttribute(localName) 方法的步骤如下:
-
如果 localName 不是 有效的属性本地名, 则抛出 "
InvalidCharacterError"DOMException。 - 如果 this 是一个 HTML 文档,则将 localName 转为 ASCII 小写。
- 返回一个新的 属性,其 本地名为 localName, 节点文档为 this。
createAttributeNS(namespace, qualifiedName) 方法的步骤如下:
-
令 (namespace、prefix、localName) 为 校验并提取 namespace 和 qualifiedName 的结果,类型为 "
attribute"。 -
返回一个新的 属性,其 命名空间为 namespace, 命名空间前缀为 prefix, 本地名为 localName, 节点文档为 this。
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 的
isTrusted属性初始化为 false。 -
取消设置 event 的 已初始化标志。
-
返回 event。
Event构造器应该被使用。
createRange() 方法的步骤是返回一个新的动态范围,以 (this, 0) 作为其起始点和结束点。
Range()构造器可以被使用。
createNodeIterator(root, whatToShow, filter)方法步骤如下:
-
设 iterator 为一个新的
NodeIterator对象。 -
将 iterator 的引用前指针设置为 true。
-
将 iterator 的whatToShow 设置为 whatToShow。
-
将 iterator 的过滤器设置为 filter。
-
返回 iterator。
createTreeWalker(root, whatToShow, filter) 方法的步骤是:
-
设 walker 为一个新的
TreeWalker对象。 -
将 walker 的whatToShow 设置为 whatToShow。
-
将 walker 的过滤器设置为 filter。
-
返回 walker。
4.5.1.接口 DOMImplementation
用户代理在创建 document 时,必须创建一个 DOMImplementation 对象,并将其与该 document 关联。
[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 (); // useless; always returns true };
doctype = document .implementation.createDocumentType(qualifiedName, publicId, systemId)- 返回一个具有给定 name、publicId 和 systemId 的文档类型。
如果 name 不是一个有效的文档类型名称,则会抛出“
InvalidCharacterError”DOMException。 doc = document .implementation. createDocument(namespace, qualifiedName [, doctype = null])- 返回一个
XMLDocument,其文档元素的本地名称为 qualifiedName,命名空间为 namespace(除非 qualifiedName 为空字符串),并且如果给定了 doctype,则将其作为其文档类型。当使用 namespace 和 qualifiedName 调用时,此方法会抛出与
createElementNS()方法相同的异常。 doc = document .implementation. createHTMLDocument([title])- 返回一个文档,其中已构建了一个基本的树,包括一个
title元素,除非省略了 title 参数。
createDocumentType(qualifiedName, publicId, systemId) 方法的步骤是:
-
如果 name 不是一个有效的文档类型名称,则抛出“
InvalidCharacterError”DOMException。 -
返回一个新的文档类型,其名称为 name,其公共 ID 为 publicId,其系统 ID 为 systemId,并将其节点文档设置为此的关联文档。
createDocument(namespace, qualifiedName, doctype) 方法的步骤是:
-
令 document 为一个新的
XMLDocument。 -
令 element 为 null。
-
如果 qualifiedName 不是空字符串,则将 element 设置为运行内部
createElementNS步骤的结果,给定 document、namespace、qualifiedName 和一个空字典。 -
如果 doctype 非空,则将 doctype 附加到 document。
-
如果 element 非空,则将 element 附加到 document。
-
document 的内容类型由 namespace 决定:
-
返回 document。
createHTMLDocument(title) 方法的步骤是:
-
将 doc 的内容类型设置为“
text/html”。 -
如果给定了 title:
-
返回 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。
创建文档类型时,总是会给出其名称。除非在创建文档类型时明确指定,否则其公共 ID 和系统 ID 均为空字符串。
publicId getter 的步骤是返回此对象的公共 ID。
systemId getter 的步骤是返回此对象的系统 ID。
4.7. 接口DocumentFragment
[Exposed =Window ]interface :DocumentFragment Node {constructor (); };
DocumentFragment 节点有一个关联的宿主(null 或不同节点树中的元素)。除非另有说明,否则它为 null。
如果对象 A 是对象 B 的包含性祖先,或者如果 B 的根节点具有非 null 的宿主并且 A 是 B 的根节点的宿主的包含宿主的包含性祖先,则对象 A 是对象 B 的包含宿主的包含性祖先。
DocumentFragment 节点的 host 概念对于 HTML 的 template 元素以及 shadow root 非常有用,并且会影响 pre-insert 和 replace 算法。
tree = newDocumentFragment()- 返回一个新的
DocumentFragment节点。
new DocumentFragment() 构造函数的步骤是将此对象的节点文档设置为当前全局对象的关联的 Document。
4.8. 接口 ShadowRoot
[Exposed =Window ]interface :ShadowRoot DocumentFragment {readonly attribute ShadowRootMode mode ;readonly attribute boolean delegatesFocus ;readonly attribute SlotAssignmentMode slotAssignment ;readonly attribute boolean clonable ;readonly attribute boolean serializable ;readonly attribute Element host ;attribute EventHandler onslotchange ; };enum {ShadowRootMode ,"open" };"closed" enum {SlotAssignmentMode ,"manual" };"named"
ShadowRoot 节点被简称为 影子根(shadow root)。
影子根有一个关联的 模式(mode)("open" 或 "closed")。
影子根有一个关联的 委托焦点(delegates focus) (布尔值)。初始值为 false。
影子根有一个关联的 对内部元素可用(available to element internals)(布尔值)。初始值为 false。
影子根有一个关联的 声明式(declarative) (布尔值)。初始值为 false。
影子根有一个关联的 插槽分配方式(slot assignment) ("manual" 或 "named")。
影子根有一个关联的 可克隆(clonable)(布尔值)。 初始值为 false。
影子根有一个关联的 可序列化(serializable)(布尔值)。 初始值为 false。
影子根有一个关联的 自定义元素注册表 (null 或 CustomElementRegistry 对象)。初始为 null。
影子根有一个关联的 保持自定义元素注册表为 null(keep custom element registry null)(布尔值)。 初始值为 false。
这只有在与声明式影子根(declarative shadow roots)一起使用时才会为 true。 并且这只在影子根的 自定义元素注册表 仍为 null 时才有意义。
一个影子根的 get the parent 算法, 给定 event,如果 event 的 composed 标志没有设置、且影子根是 event 的 路径第一个结构体的 invocation target的 根,则返回 null; 否则返回 影子根的 host。
mode 的 getter 步骤为返回 this 的 模式(mode)。
delegatesFocus 的 getter 步骤为返回 this 的 delegates focus。
slotAssignment 的 getter 步骤为返回 this 的 slot assignment。
clonable 的 getter 步骤为返回 this 的 clonable。
serializable 的 getter 步骤为返回 this 的 serializable。
host 的 getter 步骤为返回 this 的 host。
onslotchange 属性是 事件处理器 IDL 属性, 用于 onslotchange 事件处理器,其 事件类型为 slotchange。
以 包含 shadow 的树顺序(shadow-including tree order) 是对 节点树 的 带 shadow 的先序深度优先遍历。 带 shadow 的先序深度优先遍历(shadow-including preorder, depth-first traversal),对 节点树 tree,是对 tree 的先序深度优先遍历。在遍历 tree 时,每遇到一个 shadow host, 紧接着遍历该 元素的 shadow root 的 节点树。
shadow-including root(包含 shadow 的根) 指一个对象的 根的 host 的 shadow-including root,如果该对象的 根是 影子根;否则为它自己的 根。
对象 A 是 shadow-including descendant(包含 shadow 的后代), 对于对象 B,当且仅当 A 是 后代,或 A 的 根是影子根并且 A 的 根的 host 是 shadow-including inclusive descendant(包含 shadow 的自身或后代) B。
shadow-including inclusive descendant(包含 shadow 的自身或后代) 指对象自身或它的 shadow-including descendant。
对象 A 是 shadow-including ancestor(包含 shadow 的祖先), 当且仅当 B 是 shadow-including descendant A。
shadow-including inclusive ancestor(包含 shadow 的自身或祖先) 指对象自身或它的 shadow-including ancestor。
一个 节点 A 若对 节点 B 满足下列所有条件,即认为 closed-shadow-hidden(被 closed 模式的影子 DOM 隐藏):
-
A 的 根不是 shadow-including inclusive ancestor B。
-
A 的 根是 影子根,其 mode 属性为 "
closed",或者 A 的 根的 host 也是 (被 closed 模式的影子 DOM 隐藏)于 B。
要对对象 A 针对对象 B 进行 retarget(重定向),重复下列步骤直到返回一个对象为止:
-
如果下列任一成立:
则返回 A。
retarget(重定向)算法被 事件分派 以及其他规范(如 Fullscreen)使用。[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 ;SlotAssignmentMode = "named";slotAssignment boolean =clonable false ;boolean =serializable false ;CustomElementRegistry ?; };customElementRegistry
ShadowRootInit 有些不同寻常地允许向其 customElementRegistry 成员传递 undefined 和 null,从而允许 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() intentionally omitted for this example } }) </ script > <!-- "undefined" (not defined, not custom) --> < sw-han ></ sw-han > < p is = "sw-luke" ></ p > < p is = "asdf" ></ p > <!-- "failed" (not defined, not custom) --> < sw-kylo ></ sw-kylo > <!-- "uncustomized" (defined, not custom) --> < p ></ p > < asdf ></ asdf > <!-- "custom" (defined, custom) --> < sw-rey ></ sw-rey > < p is = "sw-finn" ></ p > 元素 还有一个关联的 影子根(null 或 一个 影子根)。除非另有说明,否则为 null。若其 shadow root 非空,则该 元素 为一个 shadow host。
若一个 元素 的 命名空间前缀 为 null,则其 限定名称 为其 本地名称; 否则为其 命名空间前缀,后接 ":",再接其 本地名称。
一个 元素 的 HTML 大写化的限定名称 是以下步骤的返回值:
-
令 qualifiedName 等于 this 的 qualified name。
-
如果 this 属于 HTML 命名空间,且其 节点文档是 HTML 文档,则将 qualifiedName 转为 ASCII 大写形式。
- 返回 qualifiedName。
用户代理可以通过将 qualified name 和 HTML 大写 qualified name 存储于内部槽位来优化处理。
要创建元素,给定 document 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 的构造函数。
-
设置周围代理的活动自定义元素构造函数映射[C] 为 registry。
-
在捕获任何异常的同时运行这些步骤:
-
将 result 设置为构造 C 的结果,不带参数。
-
断言:result 的 custom element state 和 custom element definition 已初始化。
-
断言:result 的 namespace 是 HTML 命名空间。
IDL 保证 result 是
HTMLElement对象,且都使用 HTML 命名空间。 -
如果 result 的 属性列表 非空, 则抛出 "
NotSupportedError"DOMException。 -
如果 result 有 子节点,则抛出 "
NotSupportedError"DOMException。 -
如果 result 的 父节点 非 null,则抛出 "
NotSupportedError"DOMException。 -
如果 result 的 节点文档不是 document,则 抛出 "
NotSupportedError"DOMException。 -
如果 result 的 local name 不等于 localName,则抛出 "
NotSupportedError"DOMException。 -
将 result 的 命名空间前缀 设置为 prefix。
-
将 result 的
is值 设置为 null。 -
将 result 的 custom element registry 设置为 registry。
如果这些步骤中的任何一个抛出异常 exception:
-
-
移除周围代理的活动自定义元素构造函数映射[C]。
在正常情况下,此时它已经被移除了。
-
-
否则:
-
将 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 document、接口 interface、字符串 localName、字符串或 null namespace、字符串或 null prefix、字符串 state、字符串或 null is,以及 null 或 CustomElementRegistry 对象 registry:
-
令 element 为一个新的 element,实现 interface, 其 namespace 设为 namespace,namespace prefix 设为 prefix,local name 设为 localName, custom element registry 设为 registry, custom element state 设为 state, custom element definition 设为 null,
is值 设为 is,节点文档 设为 document。 -
返回 element。
元素还有一个属性列表,它是一个通过 NamedNodeMap 公开的列表。除非在创建元素时明确指定,否则其属性列表为空。
本规范和其他适用规范可以为元素定义属性更改步骤。该算法传递 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 追加到一个元素 element,请运行以下步骤:
-
将 attribute 的元素设置为 element。
要移除一个属性 attribute,请运行以下步骤:
要用一个属性 newAttribute 替换一个属性 oldAttribute:
-
设 element 为 oldAttribute 的元素。
-
将 newAttribute 的元素设置为 element。
-
将 oldAttribute 的元素设置为 null。
-
为 oldAttribute(具有 element、oldAttribute 的值和 newAttribute 的值)处理属性更改。
要通过给定字符串 qualifiedName 和一个元素 element 按名称获取特性:
要通过给定 null 或字符串 namespace、字符串 localName 和一个元素 element 按命名空间和本地名称获取特性:
要通过给定一个元素 element、一个字符串 localName 以及一个可选的 null 或字符串 namespace(默认为 null)获取特性值:
要设置属性,给定一个 属性 attr 和一个 元素 element,请执行以下操作:
-
令 verifiedValue 为调用 get trusted type compliant attribute value,参数为 attr 的 本地名称、attr 的 命名空间、element 以及 attr 的 值 的结果。[TRUSTED-TYPES]
-
如果 attr 的 元素 既不是 null 也不是 element,则 抛出 "
InUseAttributeError"DOMException。 -
如果 oldAttr 是 attr,则返回 attr。
-
将 attr 的 值 设置为 verifiedValue。
-
如果 oldAttr 非 null,则用 替换 oldAttr 为 attr。
-
否则,追加 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,由一个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 的 getter 步骤是返回 this 的 namespace。
prefix 的 getter 步骤是返回 this 的 namespace prefix。
localName 的 getter 步骤是返回 this 的 local name。
tagName 的 getter 步骤是返回 this 的 HTML 大写 qualified name。
element . id [ = value ]-
返回 element 的
id内容特性的值。可以设置以更改它。 element . className [ = value ]-
返回 element 的
class内容特性的值。可以设置以更改它。 element . classList-
允许通过
DOMTokenList对象将 element 的class内容特性作为一组以空格分隔的标记进行操作。 element . slot [ = value ]-
返回 element 的
slot内容特性的值。可以设置以更改它。
定义为反映字符串 name 的 IDL 特性必须具有以下 getter 和 setter 步骤:
id 属性必须 反映 "id"。
className 属性必须 反映 "class"。
classList 的 getter 步骤是返回一个 DOMTokenList 对象,其关联的 element 为 this,且关联的 attribute 的 local name 为 class。此 DOMTokenList 对象的 token 集合也称为该 element 的 classes。
slot 属性必须 反映 "slot"。
id, class 和 slot 实际上是超级全局属性,因为它们可以出现在任何元素上,无论该元素的命名空间如何。
element . hasAttributes()-
如果 element 有特性,则返回 true;否则返回 false。
element . getAttributeNames()element . getAttribute(qualifiedName)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)element . hasAttributeNS(namespace, localName)-
如果 element 具有一个特性,其命名空间为 namespace 且本地名称为 localName,则返回 true。
hasAttributes() 方法的步骤是:如果 this 的 属性列表 为空,则返回 false;否则返回 true。
attributes 的 getter 步骤是返回关联的 NamedNodeMap。
getAttributeNames() 方法的步骤是:返回 qualified name,即 属性在 this 的 属性列表中的顺序;否则返回一个新的 列表。
这些名称不保证唯一。
getAttribute(qualifiedName) 方法步骤如下:
getAttributeNS(namespace, localName) 方法步骤如下:
setAttribute(qualifiedName, value) 方法步骤如下:
-
如果 qualifiedName 不是有效的属性本地名称,则抛出 "
InvalidCharacterError"DOMException。尽管参数的命名如此, qualifiedName 只有在已存在具有该限定名的属性时才会被用作限定名。否则,它会被用作新属性的本地名称。我们只需验证后一种情况。
-
如果 this 处于HTML 命名空间中,且其节点文档为HTML 文档,则将 qualifiedName 变为 ASCII 小写。
-
令 verifiedValue 为调用 get trusted type compliant attribute value,参数为 qualifiedName、null、this 以及 value 的结果。[TRUSTED-TYPES]
-
令 attribute 为 属性列表中第一个限定名为 qualifiedName 的属性(在 this 的属性列表中),否则为 null。
-
如果 attribute 非空,则更改 attribute 为 verifiedValue 并返回。
-
将 attribute 设为一个新属性,其本地名称为 qualifiedName,值为 verifiedValue,节点文档为 this 的节点文档。
setAttributeNS(namespace, qualifiedName, value) 方法的执行步骤如下:
-
令 (namespace, prefix, localName) 为校验并提取 namespace 和 qualifiedName 的结果,参数为 "
element"。 -
令 verifiedValue 为调用 get trusted type compliant attribute value,参数为 localName、namespace、this 及 value 的结果。[TRUSTED-TYPES]
-
为 this 使用 localName、 verifiedValue、prefix 和 namespace,设置属性值。
removeAttribute(qualifiedName) 方法的步骤为:移除属性,参数为 qualifiedName 和 this,然后返回 undefined。
removeAttributeNS(namespace, localName) 方法的步骤为:移除属性, 参数为 namespace、localName 和 this,然后返回 undefined。
hasAttribute(qualifiedName) 方法的步骤如下:
toggleAttribute(qualifiedName, force) 方法的步骤如下:
-
如果 qualifiedName 不是有效的属性本地名称,则抛出 "
InvalidCharacterError"DOMException。参见上文讨论,了解为什么我们按本地名称而不是限定名进行校验。
-
如果 this 处于HTML 命名空间中,且其节点文档为HTML 文档,则将 qualifiedName 变为 ASCII 小写。
-
令 attribute 为 属性列表中第一个限定名为 qualifiedName 的属性(在 this 的属性列表中),否则为 null。
-
如果 attribute 为 null:
-
否则,如果 force 未给定或为 false, 移除属性,参数为 qualifiedName 和 this,然后返回 false。
-
返回 true。
hasAttributeNS(namespace, localName) 方法的步骤如下:
-
如果 namespace 是空字符串,则将其设为 null。
- 如果 this 拥有一个属性,其命名空间为 namespace 且本地名称为 localName,则返回 true,否则返回 false。
getAttributeNode(qualifiedName) 方法的步骤为:返回获取属性的结果,参数为 qualifiedName 和 this。
getAttributeNodeNS(namespace, localName) 方法的步骤为:返回获取属性的结果,参数为 namespace、localName 和 this。
setAttributeNode(attr) 和 setAttributeNodeNS(attr) 方法的步骤为: 返回设置属性的结果,参数为 attr 和 this。
removeAttributeNode(attr) 方法的步骤如下:
-
如果 this 的属性列表不包含 attr,则抛出 "
NotFoundError"DOMException。 -
移除 attr。
-
返回 attr。
shadow = element .attachShadow(init)-
为 element 创建一个 shadow root 并返回它。
shadow = element .shadowRoot-
返回 element 的 shadow root(如果有),且该 shadow root 的 mode 为 "
open" 时;否则返回 null。
一个有效的影子宿主名称是:
- 一个有效的自定义元素名称
- "
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 的 is scoped 为 false,并且 registry 不是 this 的 节点文档的 自定义元素注册表,则 抛出 "
NotSupportedError"DOMException。 -
使用 附加影子根,传入 this、 init["
mode"]、 init["clonable"]、 init["serializable"]、 init["delegatesFocus"]、 init["slotAssignment"], 以及 registry。
要附加 shadow root,给定 element element、字符串 mode、布尔值 clonable、 布尔值 serializable、布尔值 delegatesFocus、字符串 slotAssignment,以及 null 或 CustomElementRegistry 对象 registry:
-
如果 element 的 命名空间不是 HTML 命名空间, 抛出 "
NotSupportedError"DOMException。 -
如果 element 的 局部名称不是 有效 shadow host 名称,抛出 "
NotSupportedError"DOMException。 -
如果 element 的 局部名称是 有效自定义元素名,或 element 的
is值 非 null:-
令 definition 为 查找自定义元素定义的结果, 参数为 element 的 custom element registry、它的 命名空间、局部名称 和
is值。 -
如果 definition 非 null 且 definition 的 disable shadow 为 true,则 抛出 "
NotSupportedError"DOMException。
-
-
如果 element 是 shadow host:
-
令 currentShadowRoot 为 element 的 shadow root。
-
如果如下任一条件为真:
-
currentShadowRoot 的 declarative 为 false;或
-
currentShadowRoot 的 mode 不等于 mode,
-
-
否则:
-
移除 currentShadowRoot 的所有 子节点, 按照 tree order。
-
将 currentShadowRoot 的 declarative 设为 false。
-
返回。
-
-
-
令 shadow 为一个新的 shadow root,其 node document 是 element 的 node document,host 为 element,并且 mode 为 mode。
-
将 shadow 的 delegates focus 设为 delegatesFocus。
-
如果 element 的 custom element state 是 "
precustomized" 或 "custom",则将 shadow 的 available to element internals 设为 true。 -
将 shadow 的 slot assignment 设为 slotAssignment。
-
将 shadow 的 declarative 设为 false。
-
将 shadow 的 clonable 设为 clonable。
-
将 shadow 的 serializable 设为 serializable。
-
将 shadow 的 custom element registry 设为 registry。
-
将 element 的 shadow root 设为 shadow。
shadowRoot 取值器的步骤如下:
-
registry = element .customElementRegistry -
返回 element 的
CustomElementRegistry对象(如果有);否则返回 null。
-
element .closest(selectors) - 返回第一个(从 element 开始的) 包含祖先,其匹配 selectors,否则返回 null。
-
element .matches(selectors) - 如果用 selectors 匹配 element 的 根节点 得到 element,则返回 true;否则返回 false。
closest(selectors) 方法的步骤如下:
-
令 s 为用 selectors 解析选择器 的结果。 [SELECTORS4]
-
如果 s 失败,则抛出 "
SyntaxError"DOMException。 -
对于 elements 中的每个 element:如果 将选择器与元素进行匹配,使用 s、element 和 作用域根 this,返回成功, 则返回 element。 [SELECTORS4]
-
返回 null。
matches(selectors) 和 webkitMatchesSelector(selectors) 方法的步骤如下:
-
令 s 为用 selectors 解析选择器 的结果。 [SELECTORS4]
-
如果 s 失败,则抛出 "
SyntaxError"DOMException。 -
如果 用选择器匹配元素 的结果(参数为 s、 this 和 作用域根 this)返回成功,则返回 true;否则,返回 false。[SELECTORS4]
getElementsByTagName(qualifiedName) 方法的步骤是返回 限定名为 qualifiedName 的元素列表,以 this 为根。
getElementsByTagNameNS(namespace, localName) 方法的步骤是返回 命名空间为 namespace 且本地名为 localName 的元素列表,以 this 为根。
getElementsByClassName(classNames) 方法的步骤是返回 类名为 classNames 的元素列表,以 this 为根。
要插入相邻节点(insert adjacent),给定一个元素element、字符串where和节点node,根据第一个与where进行ASCII大小写不敏感匹配的步骤:
- "
beforebegin" -
如果 element 的 父节点为 null,则返回 null。
- "
afterbegin" - "
beforeend" -
返回将 node 预插入到 element,在 null 前面的结果。
- "
afterend" -
如果 element 的 父节点为 null,则返回 null。
- 否则
insertAdjacentElement(where, element) 方法的步骤是返回运行 插入相邻节点(insert adjacent) 的结果,参数为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 具有一个关联的 元素(一个 element)。
一个 NamedNodeMap 对象的属性列表是其元素的属性列表。
一个 NamedNodeMap 对象的支持的属性索引是指从零到其属性列表的大小减一范围内的数字,除非该属性列表为空,在这种情况下,没有支持的属性索引。
item(index) 方法的步骤是:
NamedNodeMap 对象的支持的属性名是运行以下步骤的返回值:
-
令 names 为该 限定名 的集合,集合中的内容为该 NamedNodeMap 对象的属性列表中的所有属性(去重且有序)。
-
如果该
NamedNodeMap对象的元素在 HTML 命名空间中,并且其节点文档是HTML 文档,则 遍历 names 中的每个 name:-
令 lowercaseName 为 name 的 ASCII 小写形式。
-
如果 lowercaseName 不等于 name,则从 names 中移除 name。
-
-
返回 names。
getNamedItem(qualifiedName) 方法步骤是返回 按名称获取属性 的结果, 参数为 qualifiedName 和 element。
getNamedItemNS(namespace, localName) 方法步骤是返回 按命名空间获取属性 的结果, 参数为 namespace、localName 和 element。
setNamedItem(attr) 和 setNamedItemNS(attr) 方法步骤是返回 设置属性 的结果, 参数为 attr 和 element。
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 ; // useless; always returns true };
Attr 节点通常被称为 属性。有时为了与 IDL 属性区分,也称为内容属性。
属性具有 命名空间(null 或非空字符串), 命名空间前缀(null 或非空字符串), 本地名称(非空字符串), 值(字符串),以及 元素(null 或 元素)。
如果今天重新设计,它们可能只有 name 和 value。☹
一个 属性的 限定名,如果其 命名空间前缀为 null,则为其 本地名称; 否则为其 命名空间前缀,后接 ":",再后接其 本地名称。
用户代理可以将其作为内部槽优化。
当一个 属性被创建时,其 本地名称会被指定。除非在创建 属性时显式指定,否则其 命名空间、 命名空间前缀 和 元素 都会被设置为 null,其 值被设置为空字符串。
A 属性 是指一个 属性,其 本地名称 为 A,并且 命名空间 和 命名空间前缀 都为 null。
namespaceURI 取值器的步骤是返回 this 的 命名空间。
prefix 取值器的步骤是返回 this 的 命名空间前缀。
localName 取值器的步骤是返回 this 的 本地名称。
要设置已存在属性的值,给定 属性 attribute 和字符串 value,执行以下步骤:
-
令 element 为 attribute 的 元素。
-
令 verifiedValue 为调用 get trusted type compliant attribute value,参数为 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 nodes 使用。
每个 node 继承自 CharacterData 接口的节点都有一个关联的可变字符串,称为 data。
要替换数据(节点 node,偏移量 offset,计数 count,数据 data),请执行以下步骤:
- 令 length 为 node 的 length。
- 如果 offset 大于 length,则 抛出 "
IndexSizeError"DOMException。 - 如果 offset 加 count 大于 length,则将 count 设为 length 减 offset。
-
队列一个 mutation 记录,类型为 "
characterData",对象为 node,参数为 null, null, node 的 data, « », « », null, 和 null。 - 在 offset 代码单元之后,将 data 插入 node 的 data。
- 令 delete offset 为 offset + data 的 长度。
- 从 delete offset 代码单元开始,从 node 的 data 中移除 count 个 代码单元。
-
对每个 live range,其 start node 为 node 且 start offset 大于 offset 且小于等于 offset 加 count,将其 start offset 设为 offset。
-
对每个 live range,其 end node 为 node 且 end offset 大于 offset 且小于等于 offset 加 count,将其 end offset 设为 offset。
-
对每个 live range,其 start node 为 node 且 start offset 大于 offset 加 count,将其 start offset 增加 data 的 长度并减少 count。
-
对每个 live range,其 end node 为 node 且 end offset 大于 offset 加 count,将其 end offset 增加 data 的 长度并减少 count。
-
如果 node 的 父节点非 null,则为 node 的 父节点运行 children changed 步骤。
要截取数据,参数为节点 node、偏移量 offset 和数量 count,运行以下步骤:
- 令 length 为 node 的 length。
- 如果 offset 大于 length,则 抛出 "
IndexSizeError"DOMException。 - 如果 offset 加 count 大于 length,则返回一个字符串,其值为从第 offset 个 代码单元到 node 的 data 末尾的所有代码单元,然后返回。
- 返回一个字符串,其值为从第 offset 个 代码单元到第 offset+count 个 代码单元,在 node 的 data 中。
data 取值器的步骤是返回 this 的 数据。其赋值器必须用节点 this、偏移量 0、 计数 this 的 长度,以及新的数据值来替换数据。
substringData(offset, count) 方法的步骤是返回使用节点 this、 偏移量 offset 和计数 count 运行 子串数据 的结果。
appendData(data) 方法的步骤是 使用节点 this、偏移量 this 的 长度、计数 0,以及数据 data 来 替换数据。
insertData(offset, data) 方法的步骤是使用节点 this、偏移量 offset、计数 0,以及数据 data 来 替换数据。
deleteData(offset, count) 方法的步骤是使用节点 this、偏移量 offset、计数 count 以及空字符串作为数据来 替换数据。
replaceData(offset, count, data) 方法的步骤是使用节点 this、偏移量 offset、计数 count 以及数据 data 来 替换数据。
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 节点是指不是 CDATASection 节点的 Text 节点。
连续的 Text 节点,对于某 节点 node 来说,是指 node、node 的 前一个兄弟 Text 节点(如果有的话)及其 连续 Text 节点,以及 node 的 下一个兄弟 Text 节点(如果有的话)及其 连续 Text 节点,避免重复。
连续独占 Text 节点,对于某 节点 node,指的是 node 、node 的 前一个兄弟 独占型 Text 节点(如有)及其 连续独占 Text 节点,还有 node 的 下一个兄弟 独占型 Text 节点(如有)及其 连续独占 Text 节点,避免重复。
子文本内容(child text content),对于某 节点 node,是指 node 所有 Text 节点 子节点 的 数据 按 树顺序 拼接后的结果。
后代文本内容(descendant text content),对于 节点 node,是其所有 Text 节点 后代 的 数据 按 树顺序 拼接后的结果。
new Text(data) 构造方法的步骤为:将 this 的 数据 设为 data,this 的 节点文档 设为 当前全局对象的 相关 Document。
要分割一个 Text 节点 node 于偏移 offset,按照下列步骤执行:
- 令 length 为 node 的 长度。
- 如果 offset 大于 length,则抛出 "
IndexSizeError"DOMException。 - 令 count 为 length 减去 offset。
- 令 new data 为用节点 node、偏移 offset 和计数 count 子串数据 的结果。
- 令 new node 为一个新的
Text节点,其 节点文档与 node 相同。将 new node 的 数据 设为 new data。 - 令 parent 为 node 的 父节点。
-
如果 parent 不为 null:
- 替换数据,节点为 node,偏移为 offset,计数为 count,新数据为空字符串。
- 返回 new node。
splitText(offset) 方法的步骤是使用偏移 offset 分割 this。
wholeText 的 getter 步骤为返回 拼接 数据 的 连续 Text 节点(以 树顺序)的全部数据,针对 this。
4.12. 接口 CDATASection
[Exposed =Window ]interface :CDATASection Text { };
4.13. 接口 ProcessingInstruction
[Exposed =Window ]interface :ProcessingInstruction CharacterData {readonly attribute DOMString target ; };
ProcessingInstruction 节点 有一个关联的 目标(target)。
target 的 getter 步骤是返回 this 的 target。
4.14. 接口 注释
[Exposed =Window ]interface :Comment CharacterData {constructor (optional DOMString = ""); };data
comment = new Comment([data = ""])- 返回一个新的
Comment节点,其 data 为 data。
new Comment(data) 构造函数的步骤是将 this 的 data 设置为 data, 并将 this 的 节点文档 设置为 当前全局对象 的 关联 Document。
5. Ranges
5.1. Introduction to "DOM Ranges"
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 ) // do not forget the leading space range. setEnd( secondText, 4 ) // range now stringifies to the aforementioned quote 像上面节点树中的 src 和 alt 这样的属性不能用范围来表示。范围仅对节点有用。
Range 对象与 StaticRange 对象不同,它会受到节点树突变的影响。因此它们也被称为活动范围。此类突变不会使其失效,并将尝试确保它仍然表示相同的内容片段。必要时,当例如它所表示的部分内容发生突变时,活动范围本身可能会作为节点树突变的一部分而被修改。
有关详细信息,请参阅插入和移除算法、normalize() 方法以及替换数据和分割算法。
响应节点树突变来更新活动范围的成本可能很高。对于节点树的每次更改,所有受影响的 Range 对象都需要更新。即使应用程序对某些活动范围不感兴趣,当发生突变时,它仍然必须支付保持它们最新的成本。
一个 StaticRange 对象是一个轻量级的范围,当节点树发生突变时它不会更新。因此,它不像活动范围那样需要相同的维护成本。
5.2. Boundary points
一个边界点是一个由节点(一个节点)和一个偏移量(一个非负整数)组成的元组。
一个正确的边界点的偏移量将在 0 和该边界点的节点的长度之间(包含边界)。
一个边界点 (nodeA, offsetA) 相对于另一个边界点 (nodeB, offsetB) 的位置是之前、相等或之后,具体由以下步骤返回:
-
断言:nodeA 和 nodeB 具有相同的根。
- 如果 nodeA 与 nodeB 相同,则如果 offsetA 与 offsetB 相同,则返回相等;如果 offsetA 小于 offsetB,则返回之前;如果 offsetA 大于 offsetB,则返回之后。
-
如果 nodeA 在 nodeB 之后,则如果 (nodeB, offsetB) 相对于 (nodeA, offsetA) 的位置是之前,则返回之后;如果它是之后,则返回之前。
-
如果 nodeA 是 nodeB 的一个祖先:
-
返回之前。
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。
startContainer 取值步骤为返回 this 的 起始节点。
startOffset 取值步骤为返回 this 的 起始偏移。
endContainer 取值步骤为返回 this 的 结束节点。
endOffset 取值步骤为返回 this 的 结束偏移。
collapsed 取值步骤为:如果 this 是折叠的则返回 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 的 start 设为 (init["
startContainer"], init["startOffset"]) ,end 设为 (init["endContainer"], init["endOffset"])。
如果以下所有条件均为真,则 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, 0) 在 range 的起始点之后,并且 (node, node的长度) 在 range 的结束点之前,则该节点 node 包含在活动范围 range 中。
如果一个节点是活动范围的起始节点的包含祖先但不是其结束节点的包含祖先,反之亦然,则该节点部分包含在该活动范围中。
以下事实有助于更好地理解这些定义:
活动范围移除前步骤,给定一个node node,如下所示:
range = new Range()- 返回一个新的活动范围。
new Range() 构造方法的步骤是 将 this 的 start 和 end 设为 (当前全局对象的 关联 Document, 0)。
- container = range .
commonAncestorContainer - 返回一个节点,它是距离文档最远并且同时作为 range 的起始节点和结束节点的祖先。
commonAncestorContainer getter 的步骤是:
要将range的起始点或结束点设置为一个边界点 (node, offset),请执行以下步骤:
- 如果 node 是 doctype,则 抛出 "
InvalidNodeTypeError"DOMException。 - 如果 offset 大于 node 的 length,则 抛出一个 "
IndexSizeError"DOMException。 - 令 bp 为 边界点 (node, offset)。
setStart(node, offset) 方法 步骤是将 起始设置为 this 的 边界点 (node, offset)。
setEnd(node, offset) 方法 步骤是将 结束设置为 this 的 边界点 (node, offset)。
setStartBefore(node) 方法步骤如下:
- 令 parent 为 node 的 父节点。
- 如果 parent 为 null,则 抛出一个 "
InvalidNodeTypeError"DOMException。 - 设置起始到 this 的 边界点 (parent, node 的 索引)。
setStartAfter(node) 方法的步骤是:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出一个 "
InvalidNodeTypeError"DOMException。
setEndBefore(node) 方法步骤如下:
- 令 parent 为 node 的 父节点。
- 如果 parent 为 null,则 抛出一个 "
InvalidNodeTypeError"DOMException。 - 设置结束到 this 的 边界点 (parent, node 的 索引)。
setEndAfter(node) 方法步骤如下:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出一个 "
InvalidNodeTypeError"DOMException。
collapse(toStart) 方法步骤是:如果 toStart 为 true,则将 结束设为 起始;否则将 起始设为 结束。
要选择在 range range 中的 节点 node,运行如下步骤:
-
令 parent 为 node 的 父节点。
-
如果 parent 为 null,则 抛出一个 "
InvalidNodeTypeError"DOMException。 -
令 index 为 node 的 索引。
selectNode(node) 方法步骤是 在 this 上 选择 node。
selectNodeContents(node) 方法步骤如下:
-
如果 node 是 doctype,抛出一个 "
InvalidNodeTypeError"DOMException。 -
令 length 为 node 的 length。
compareBoundaryPoints(how, sourceRange) 方法的步骤是:
-
如果 how 不是以下之一
则 抛出一个 "
NotSupportedError"DOMException。 - 如果 this 的 根 不等于 sourceRange 的 根,则 抛出一个 "
WrongDocumentError"DOMException。 - 如果 how 为:
START_TO_START:- 令 this point 为 this 的 起始。 令 other point 为 sourceRange 的 起始。
START_TO_END:- 令 this point 为 this 的 结束。 令 other point 为 sourceRange 的 起始。
END_TO_END:- 令 this point 为 this 的 结束。 令 other point 为 sourceRange 的 结束。
END_TO_START:- 令 this point 为 this 的 起始。 令 other point 为 sourceRange 的 结束。
-
如果 this point 相对于 other point 的 位置为
deleteContents() 方法步骤如下:
- 令 original start node、original start offset、original end node 和 original end offset 分别为 this 的 起始节点、 起始偏移、 结束节点 和 结束偏移。
-
如果 original start node 等于 original end node 且其为
CharacterData节点,则 用节点 original start node、偏移 original start offset、计数 original end offset 减去 original start offset 以及空字符串作为新数据执行 替换数据,然后返回。 - 令 nodes to remove 为所有在 节点,它们被 包含于 this 中,按 树序排列,并且省略任何其 父节点 也被 包含于 this 的节点的列表。
- 如果 original start node 是 original end node 的 包含自身祖先,则设置 new node 为 original start node,new offset 为 original start offset。
- 否则:
- 令 reference node 等于 original start node。
- 当 reference node 的 父节点 不为 null 且不是 original end node 的包含性祖先时, 令 reference node 为其 父节点。
- 令 new node 为 reference node 的 父节点,new offset 为 reference node 的 索引 加 1。
如果 reference node 的 父节点 为 null,那么它就是 this 的根,所以会是 original end node 的包含性祖先,因此无法进入该分支。
-
如果 original start node 是
CharacterData节点,则以节点 original start node、偏移 original start offset、计数 original start node 的 长度减去 original start offset 和数据为空字符串执行 替换数据。 -
如果 original end node 是
CharacterData节点,则以节点 original end node,偏移为 0,计数为 original end offset 和数据为空字符串执行 替换数据。 - 将 start 和 end 设置为 (new node, new offset)。
要对一个活动范围(live range) range执行提取(extract),按照下列步骤:
-
令 fragment 为一个新的
DocumentFragment节点,其 节点文档 为 range 的 起始节点 的 节点文档。 -
如果 range 是 折叠的,则返回 fragment。
- 令 original start node、original start offset、original end node 和 original end offset 分别为 range 的 起始节点、 起始偏移、 结束节点 和 结束偏移。
-
如果 original start node 和 original end node 相同,并且它是
CharacterData节点:- 令 clone 为 original start node 的克隆。
- 设置 clone 的 数据 为通过对节点 original start node 截取数据(substringing data), 起始为 original start offset,长度为 original end offset 减去 original start offset 的结果。
- 附加 clone 到 fragment。
- 替换数据(节点 original start node,偏移 original start offset,计数 original end offset 减 original start offset,数据为空字符串)。
- 返回 fragment。
- 令 common ancestor 为 original start node。
- 当 common ancestor 不是 original end node 的包含性祖先时,令 common ancestor 为其父节点。
- 令 first partially contained child 为 null。
- 如果 original start node 不是 original end node 的 包含性祖先,则令 first partially contained child 为 common ancestor 的第一个在 range 中 部分被包含的子节点。
- 令 last partially contained child 为 null。
- 如果 original end node 不是 original start node 的包含性祖先,则令 last partially contained child 为 common ancestor 的最后一个在 range 中 部分被包含的子节点。
这些变量赋值总是有意义。比如如果 original start node 不是 original end node 的包含性祖先,那么 original start node 自身就是 range 的部分被包含节点,其所有祖先直到 common ancestor 的某个子节点也都是部分被包含的。 common ancestor 不会是 original start node,因为它必须是 original end node 的包含性祖先。反之也成立。并且若两者都被定义,它们永远不会相等。
- 令 contained children 为 common ancestor 所有在 range 里 被包含的子节点列表,顺序为树序。
-
如果 contained children 的任何一个成员是 doctype,则抛出 "
HierarchyRequestError"DOMException。不必担心第一个或最后一个部分被包含节点,因为doctype 不会是部分被包含节点,不能作为范围的边界点,也不能是其它节点的祖先。
- 如果 original start node 是 original end node 的包含性祖先,则令 new node 为 original start node,new offset 为 original start offset。
- 否则:
-
如果 first partially contained child 是
CharacterData节点:此时 first partially contained child 即为 original start node。
-
令 clone 为 original start node 的克隆。
-
设置 clone 的 数据 为对节点 original start node 执行 substringing data(起始 original start offset,长度为 original start node 的 长度减 original start offset)的结果。
-
附加 clone 到 fragment。
-
替换数据(节点 original start node,偏移 original start offset,计数 original start node 的 长度减 original start offset,数据为空字符串)。
-
- 否则,如果 first partially contained child 不为 null:
-
对 contained children 的每个 contained child: 附加 contained child 到 fragment。
-
如果 last partially contained child 是
CharacterData节点:此时 last partially contained child 即为 original end node。
- 令 clone 为 original end node 的克隆。
- 设置 clone 的 数据 为通过对 original end node 执行 substringing data(偏移 0,计数为 original end offset)的结果。
- 附加 clone 到 fragment。
- 替换数据(节点 original end node,偏移 0,计数 original end offset,数据为空字符串)。
- 否则,如果 last partially contained child 不为 null:
- 将 range 的 起始 和 结束 设置为 (new node, new offset)。
- 返回 fragment。
extractContents() 方法步骤为,返回对 提取 this 的结果。
要克隆内容于一个 活动范围range,执行如下步骤:
-
令 fragment 为一个新的
DocumentFragment节点,其 节点文档 是 range 的 起始节点 的 节点文档。 -
如果 range 是 折叠的,则返回 fragment。
- 令 original start node、original start offset、original end node 和 original end offset 分别为 range 的 起始节点、 起始偏移、 结束节点、 和 结束偏移。
-
如果 original start node 等于 original end node 且它是
CharacterData节点:- 令 clone 为 original start node 的 克隆。
- 设置 clone 的 数据 为对节点 original start node 执行 substringing data,使用偏移 original start offset 和计数 original end offset 减 original start offset 的结果。
- 将 clone 添加到 fragment。
- 返回 fragment。
- 令 common ancestor 为 original start node。
- 当 common ancestor 不是 original end node 的 包含性祖先 时,将 common ancestor 设为它自己的 父节点。
- 令 first partially contained child 为 null。
- 如果 original start node 不是 original end node 的 包含性祖先,将 first partially contained child 设为 common ancestor 的第一个在 range 中 部分被包含的 子节点。
- 令 last partially contained child 为 null。
- 如果 original end node 不是 original start node 的 包含性祖先,将 last partially contained child 设为 common ancestor 的最后一个在 range 中 部分被包含的 子节点。
这些变量赋值实际上总是合理的。例如,如果 original start node 不是 original end node 的 包含性祖先,则 original start node 本身就是 range 中部分被包含的节点, 其所有祖先直到 common ancestor 的某个子节点也都是如此。common ancestor 不可能是 original start node,因为它必须是 original end node 的包含性祖先。另一个情况类似。此外注意如果两者都已定义,它们绝不会相等。
- 令 contained children 为 common ancestor 所有在 range 内 被包含的子节点列表,树序排列。
-
如果 contained children 中有成员是 doctype,则抛出 "
HierarchyRequestError"DOMException。无须关心第一个或最后一个部分被包含节点,因为 doctype 永远不可能部分被包含。它不能作为范围的边界点,也不能成为其他节点的祖先。
-
如果 first partially contained child 是
CharacterData节点:此时 first partially contained child 即为 original start node。
-
令 clone 为 original start node 的 克隆。
-
设置 clone 的 数据 为对 original start node 执行 substringing data, 起始为 original start offset,计数为 original start node 的 长度减去 original start offset 的结果。
-
将 clone 添加到 fragment。
-
-
否则,如果 first partially contained child 不为 null:
-
对于 contained children 中的每个 contained child:
-
如果 last partially contained child 是
CharacterData节点:此时 last partially contained child 即为 original end node。
- 令 clone 为 original end node 的 克隆。
- 设置 clone 的 数据 为对 original end node 执行 substringing data,偏移 0,计数为 original end offset 的结果。
- 将 clone 添加到 fragment。
-
否则,如果 last partially contained child 不为 null:
- 返回 fragment。
cloneContents() 方法步骤为,返回对 克隆内容 this 的结果。
要将节点node插入到活动范围range中,按以下步骤执行:
- 如果range的起始节点是
ProcessingInstruction或Comment节点,或其为Text节点且父节点为null,或者等于node,则抛出 "HierarchyRequestError"DOMException。 - 令referenceNode为null。
- 如果range的起始节点是
Text节点,则将referenceNode设为该Text节点。 - 否则,将referenceNode设为起始节点的子节点,其索引等于起始偏移,若无该子节点则为null。
- 令parent为:若referenceNode为null,则为range的起始节点,否则为referenceNode的父节点。
- 确保预插入的合法性:在parent中,在referenceNode之前插入node。
- 如果range的起始节点是
Text节点,则将referenceNode设为对其用range的起始偏移进行分割后的结果。 - 如果node与referenceNode相同,则将referenceNode设为其下一个兄弟节点。
-
令newOffset为:如果referenceNode为null,则为parent的长度;否则为referenceNode的索引。
-
如果node为
DocumentFragment节点,则将newOffset增加node的长度,否则增加1。 - 预插入: 在parent中,在referenceNode之前插入node。
insertNode(node)方法的步骤是将node插入到this中。
surroundContents(newParent)方法的步骤如下:
-
如果在this中有一个非
Text节点被部分包含,则抛出"InvalidStateError"DOMException。 -
如果newParent是
Document、DocumentType或DocumentFragment节点,则抛出"InvalidNodeTypeError"DOMException。出于历史原因,
CharacterData节点不会在这里检查,而是在执行过程中抛出异常。 -
如果newParent有子节点,则在newParent内用null替换所有内容。
-
将fragment附加到newParent。
cloneRange() 方法步骤为,返回一个新的活动范围,其 起始 和 结束与 this 相同。
detach() 方法步骤为不执行任何操作。 其功能(禁用 Range 对象)已被移除,但方法本身为兼容性而保留。
- position = range .
comparePoint(node, offset) - 如果点在范围之前返回 −1,如果点在范围内返回 0,如果点在范围之后返回 1。
- intersects = range .
intersectsNode(node) - 返回 range 是否与 node 相交。
The isPointInRange(node, offset) 方法步骤如下:
- 如果 node 的 root 与 this 的 root 不同,则返回 false。
- 如果 node 是一个 doctype,则 throw 一个 "
InvalidNodeTypeError"DOMException。 -
如果 offset 大于 node 的 length,则 throw 一个 "
IndexSizeError"DOMException。 - 如果 (node, offset) 在 before start 或 在 after end,则返回 false。
- 返回 true。
The comparePoint(node, offset) 方法步骤如下:
- 如果 node 的 root 与 this 的 root 不同,则 throw 一个 "
WrongDocumentError"DOMException。 - 如果 node 是一个 doctype,则 throw 一个 "
InvalidNodeTypeError"DOMException。 -
如果 offset 大于 node 的 length,则 throw 一个 "
IndexSizeError"DOMException。 - 如果 (node, offset) 在 before start,返回 −1。
- 如果 (node, offset) 在 after end,返回 1。
- 返回 0。
The intersectsNode(node) 方法步骤如下:
The stringification behavior 必须执行以下步骤:
-
令 s 为空字符串。
-
如果 this 的 起始节点 等于 this 的 结束节点,并且它是一个
Text节点,则返回该Text节点 的 数据,区间是从 this 的 起始偏移 到 this 的 结束偏移 的子字符串。 -
如果 this 的 起始节点 是
Text节点,则将该 节点 的 数据,从 this 的 起始偏移 到结尾的子字符串追加到 s。 -
如果 this 的 结束节点 是
Text节点,则将该 节点 的 数据,从开始到 this 的 结束偏移 的子字符串追加到 s。 -
返回 s。
createContextualFragment()、 getClientRects()、 和 getBoundingClientRect() 方法在其他规范中定义。 [DOM-Parsing] [CSSOM-VIEW]
6. 遍历
NodeIterator 和 TreeWalker 对象可以用来过滤和遍历节点 树。
每个 NodeIterator 和 TreeWalker 对象都有一个关联的 活跃标志,用于避免递归调用。该标志初始状态为未设定。
每个 NodeIterator 和 TreeWalker 对象还有一个关联的 根节点(节点),一个 whatToShow(位掩码),以及一个 筛选器(回调)。
要在 NodeIterator 或 TreeWalker 对象 traverser 内对 节点node 进行 过滤,执行以下步骤:
-
如果 traverser 的 活跃标志已设定,则抛出 “
InvalidStateError”DOMException。 -
令 n 为 node 的
nodeType属性值减 1。 -
如果 traverser 的 whatToShow 的第 n 位(0为最低位)未被设定,则返回
FILTER_SKIP。 -
如果 traverser 的 筛选器为 null,则返回
FILTER_ACCEPT。 -
设置 traverser 的 活跃标志。
-
令 result 为以 traverser 的 筛选器、"acceptNode" 和 « node » 调用 用户对象操作的返回值。如果此处抛出异常,则取消设置 traverser 的 活跃标志 并重新抛出该异常。
-
取消设置 traverser 的 活跃标志。
-
返回 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 对象还有一个关联的 参考节点(节点)和 参考节点之前的指针(布尔值)。
如前所述,NodeIterator 对象还关联有 活跃标志、根节点、whatToShow 和 筛选器。
给定 nodeIterator 和 toBeRemovedNode,NodeIterator 移除前步骤 如下:
-
如果 toBeRemovedNode 不是 nodeIterator 的 参考节点 的 包含性祖先, 或 toBeRemovedNode 是 nodeIterator 的 根节点,则返回。
-
如果 nodeIterator 的 参考节点之前的指针 为 true:
-
将 nodeIterator 的 参考节点,设置为如下: 若 toBeRemovedNode 的 前一个兄弟节点 为 null,则为 toBeRemovedNode 的 父节点; 否则,为 toBeRemovedNode 的前一个兄弟节点中在树序中最后出现的包含性后代。
root 的 getter 步骤为返回 this 的 根节点。
referenceNode 的 getter 步骤为返回 this 的 参考节点。
pointerBeforeReferenceNode 的 getter 步骤为返回 this 的 参考节点之前的指针。
whatToShow 的 getter 步骤为返回 this 的 whatToShow。
filter 的 getter 步骤为返回 this 的 筛选器。
要遍历,给定一个 NodeIterator 对象 iterator 和方向 direction,执行以下步骤:
-
令 node 为 iterator 的 参考节点。
-
令 beforeNode 为 iterator 的 参考节点之前的指针。
-
一直循环:
-
根据 direction 分支:
-
令 result 为在 iterator 内对 node 过滤 的结果。
-
如果 result 为
FILTER_ACCEPT,则跳出。
-
-
将 iterator 的 参考节点 设为 node。
-
将 iterator 的 参考节点之前的指针 设为 beforeNode。
-
返回 node。
nextNode() 方法的步骤为返回对 遍历(参数为 this 和 next)的结果。
previousNode() 方法的步骤为返回对 遍历(参数为 this 和 previous)的结果。
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 对象有一个关联的 current(一个节点)。
如前所述,TreeWalker 对象还关联有 根节点、 whatToShow 和 筛选器。
root 的 getter 步骤为返回 this 的 根节点。
whatToShow 的 getter 步骤为返回 this 的 whatToShow。
filter 的 getter 步骤为返回 this 的 筛选器。
currentNode 的 getter 步骤为返回 this 的 current。
currentNode 的 setter 步骤为将 this 的 current 设置为给定的值。
parentNode() 方法的步骤如下:
-
返回 null。
要遍历子节点,给定 walker 和 type,执行以下步骤:
-
令 node 为 walker 的 current。
-
如果 type 为 first,则将 node 设为 node 的 第一个子节点;如果 type 为 last,则设为 node 的 最后一个子节点。
-
当 node 非空时:
-
令 result 为 过滤 node 于 walker 的结果。
-
如果 result 为
FILTER_ACCEPT,则将 walker 的 current 设为 node 并返回 node。 -
如果 result 为
FILTER_SKIP: -
当 node 非空时:
-
-
返回 null。
firstChild() 方法的步骤是使用 遍历子节点,参数为 this 和 first。
lastChild() 方法的步骤是使用 遍历子节点,参数为 this 和 last。
要遍历兄弟节点,给定 walker 和 type,执行以下步骤:
-
令 node 为 walker 的 current。
-
如果 node 是 根节点,则返回 null。
-
一直循环:
-
如果 type 为 next,则令 sibling 为 node 的 下一个兄弟节点, 如果为 previous,则为 node 的 前一个兄弟节点。
-
当 sibling 非空时:
-
将 node 设为 sibling。
-
令 result 为 过滤 node 于 walker 的结果。
-
如果 result 为
FILTER_ACCEPT,则将 walker 的 current 设为 node 并返回 node。 -
如果 type 为 next,则令 sibling 为 node 的 第一个子节点, 如果为 previous,则为 node 的 最后一个子节点。
-
如果 result 是
FILTER_REJECT或 sibling 为 null,则 如果 type 为 next,则令 sibling 为 node 的 下一个兄弟节点, 如果为 previous,则为 node 的 前一个兄弟节点。
-
-
将 node 设为 node 的 父节点。
-
如果 node 为 null 或 walker 的 根节点,则返回 null。
-
如果 过滤 node 于 walker 的结果为
FILTER_ACCEPT,则返回 null。
-
nextSibling() 方法的步骤是以 遍历兄弟节点,参数为 this 和 next。
previousSibling() 方法的步骤是以 遍历兄弟节点,参数为 this 和 previous。
previousNode() 方法的步骤如下:
-
返回 null。
nextNode() 方法的步骤如下:
-
令 result 为
FILTER_ACCEPT。 -
一直循环:
-
当 result 不是
FILTER_REJECT且 node 有子节点时: -
令 sibling 为 null。
-
令 temporary 为 node。
-
当 temporary 非空时:
-
如果 result 为
FILTER_ACCEPT, 则将 this 的 current 设为 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 对象可以用作 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 对象有一个关联的 token set(一个 集合),初始为空。
DOMTokenList 对象还有一个关联的 element 和 attribute 的 local name。
规范可以为 DOMTokenList 关联的 attribute 的 local name 定义 supported tokens。
DOMTokenList 对象的 validation steps 针对给定 token 如下:
-
如果关联的 attribute 的 local name 未定义 supported tokens,则 抛出
TypeError。 -
令 lowercase token 为 token 的副本,并转为 ASCII 小写。
-
如果 lowercase token 存在于 supported tokens 中,返回 true。
-
返回 false。
DOMTokenList 对象的 update steps 如下:
-
为关联的 element,用关联的 attribute 的 local name 和 ordered set serializer 处理 token set 的结果,设置属性值。
DOMTokenList 对象的 serialize steps 是返回以关联的 element 和关联的 attribute 的 local name 为参数 get an attribute value 的结果。
DOMTokenList 对象有如下针对其关联 attribute change steps 的 element:
-
如果 localName 为关联属性的 local name,namespace 为 null,且 value 为 null,则 清空 token set。
-
否则,如果 localName 为关联属性的 local name,namespace 为 null,则将 token set 设为 value 解析的结果。
当创建一个 DOMTokenList 对象时:
-
令 element 为关联的 element。
-
令 localName 为关联属性的 local name。
-
令 value 为用 element 和 localName 获取属性值 的结果。
-
为 element、localName、value、value 和 null 执行 attribute change steps。
-
tokenlist .length -
返回 token 的数量。
-
tokenlist .item(index)tokenlist[index] -
返回索引为 index 的 token。
-
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) -
用 newToken 替换 token。
如果 token 被替换返回 true,否则返回 false。
如果其中一个参数为空字符串,则抛出 "
SyntaxError"DOMException。如果其中一个参数包含任何 ASCII 空白,则抛出 "
InvalidCharacterError"DOMException。 -
tokenlist . supports(token) -
如果 token 在关联属性的 supported tokens 中则返回 true,否则返回 false。
如果关联属性未定义 supported tokens,则抛出
TypeError。 -
tokenlist .value -
以字符串形式返回关联的集合。
可设值,用于更改关联属性。
length 属性的 getter 必须返回 this 的 token set 的 size。
该对象的 supported property indices 是从零到对象 token set 的 size 减一的数字,除非 token set 为空,这种情况下没有 supported property indices。
item(index) 方法步骤如下:
contains(token) 方法的步骤是:如果 this 的 token set[token] 存在,返回 true,否则返回 false。
add(tokens…) 方法步骤如下:
-
遍历 tokens 中的每个 token:
-
如果 token 为空字符串,则 抛出 "
SyntaxError"DOMException。 -
如果 token 含有任何 ASCII 空白,则 抛出 "
InvalidCharacterError"DOMException。
-
-
执行 update steps。
remove(tokens…) 方法步骤如下:
-
遍历 tokens 中的每个 token:
-
如果 token 为空字符串,则 抛出 "
SyntaxError"DOMException。 -
如果 token 含有任何 ASCII 空白,则 抛出 "
InvalidCharacterError"DOMException。
-
-
执行 update steps。
toggle(token, force) 方法步骤如下:
-
如果 token 为空字符串,则 抛出 "
SyntaxError"DOMException。 -
如果 token 含有任何 ASCII 空白,则 抛出 "
InvalidCharacterError"DOMException。 -
如果 this 的 token set[token] 存在:
-
如果 force 未给定或为 false,则 移除 token 从 this 的 token set,执行 update steps 并返回 false。
-
返回 true。
-
-
否则,如果 force 未给定或为 true,追加 token 到 this 的 token set,执行 update steps,并返回 true。
-
返回 false。
update steps 并不总是为 toggle() 运行,以保证 web 兼容性。
replace(token, newToken) 方法步骤如下:
-
如果 token 或 newToken 为空字符串,则 抛出 "
SyntaxError"DOMException。 -
如果 token 或 newToken 含有任何 ASCII 空白,则 抛出 "
InvalidCharacterError"DOMException。 -
执行 update steps。
-
返回 true。
update steps 并不总是为 replace() 运行,以保证 web 兼容性。
supports(token) 方法步骤如下:
-
令 result 为以 token 调用 validation steps 的返回值。
-
返回 result。
value 属性必须返回执行 this 的 serialize steps 的结果。
设置 value 属性必须使用关联的 element、关联的 attribute 的 local name 和给定值 设置属性值。
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 ;
The createNSResolver(nodeResolver) 方法步骤是返回 nodeResolver。
此方法仅因历史原因存在。
8.4. 接口 XPathEvaluator
[Exposed =Window ]interface {XPathEvaluator (); };constructor XPathEvaluator includes XPathEvaluatorBase ;
由于历史原因,您既可以构造 XPathEvaluator 也可以在 Document 上访问相同的方法。
9. XSLT
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, 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, 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, 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 许可证进行许可。
这是现行标准。那些对专利审查版本感兴趣的人应该查看现行标准审查草案。