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,作用域匹配选择器字符串 的步骤如下:
-
令 selector 为 解析选择器 selectors 的结果。 [SELECTORS4]
-
如果 selector 返回失败,则 抛出一个 "
SyntaxError"DOMException。 -
返回 selector 与 node 的 根节点 通过 作用域根 node 进行 在树中匹配选择器 的结果。[SELECTORS4]。
不打算支持在选择器中使用命名空间,也不会添加此功能。
1.4. 名称验证
当一个字符串name满足下列步骤返回 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,请按以下步骤操作: