UI事件

W3C 工作草案,

关于本文档的更多详情
此版本:
https://www.w3.org/TR/2024/WD-uievents-20240907/
最新发布版本:
https://www.w3.org/TR/uievents/
编辑草案:
https://w3c.github.io/uievents/
以往版本:
历史记录:
https://www.w3.org/standards/history/uievents/
反馈:
GitHub
规范内反馈
编辑:
(Google)
(Microsoft)
前任编辑:
Doug Schepers (2008年3月 - 2011年5月)
测试:
web-platform-tests uievents/ (持续工作中)

摘要

本规范定义了扩展 [DOM] 中定义的 DOM 事件对象的 UI 事件。UI 事件通常由可视化用户代理实现,用于处理用户交互,例如鼠标和键盘输入。

本文档状态

本章节描述了本文档在发布时的状态。当前 W3C 出版物列表及本技术报告的最新修订版,可在 W3C 技术报告索引 https://www.w3.org/TR/ 上查阅。

本文档由 Web 应用工作组 以工作草案形式发布。本文件旨在成为 W3C 推荐标准。

本文档由 Web 应用工作组 以工作草案形式,并采用 推荐标准流程 发布。 欢迎对本规范提供反馈和评论,请使用 GitHub issues 历史讨论可在 public-webapps@w3.org 存档中查阅。

作为工作草案发布并不代表 W3C 及其成员的认可。该文件为草案,可能随时被更新、替换或废止。除了作为进行中的工作外,不适合引用本文档。

本文档由遵循 W3C 专利政策 的小组制作。W3C 维护一份 公开专利披露列表,该页面亦包含专利披露的说明。如个人实际知悉某专利并认为其中包含 必要声明,则必须根据 第6节 W3C 专利政策 披露相关信息。

本文档受 2023年11月3日 W3C 流程文件 约束。

1. 介绍

1.1. 概述

UI Events 设计有两个主要目标。第一个目标是设计一个 事件 系统,该系统允许注册 事件监听器, 并描述事件在树结构中的流动方式。此外,本规范将为用户界面控制和文档变更通知提供标准事件模块,并为这些事件模块定义相关的上下文信息。

UI Events 的第二个目标是提供当前主流浏览器所用事件系统的通用子集,旨在促进现有脚本和内容的互操作性。并不期望该目标能实现完全的向后兼容,但规范会在可能时予以实现。

1.2. 一致性

本节为规范性内容。

在本规范中,关键词 MUSTMUST NOTREQUIREDSHALLSHALL NOTSHOULDSHOULD NOTRECOMMENDEDMAYOPTIONAL 应按 [RFC2119] 所述进行解释。

本规范应结合 DOM Level 3 Core 规范 [DOM-Level-3-Core] 理解,并适用 DOM 实现的一般考虑。例如,命名空间 URI 的处理在 XML 命名空间 中讨论。有关 一致性 的更多信息,请参见 DOM Level 3 Core 规范 [DOM-Level-3-Core]用户代理 无需完全符合其他规范即可符合本规范,但必须符合本规范所引用的其他规范的相关部分(例如,符合 UI Events 的 用户代理 必须支持 DOMString 数据类型(见 [WebIDL]),但不需要支持 [WebIDL] 中的所有方法或数据类型才能符合 UI Events)。

本规范为不同的 用户代理、规范及内容作者定义了多种一致性类别:

1.2.1. 网页浏览器及其他动态或交互式 用户代理

动态或交互式 用户代理(以下简称“浏览器”,包括 Web 浏览器、辅助技术(AT)应用程序或其他类似程序)符合 UI Events 的要求,如果其支持:

符合要求的浏览器在满足某 事件分发 的条件时,必须将事件分发至相应的 EventTarget

浏览器若实现本文件中规定的接口及相关 事件类型 ,则被视为符合 UI Events。

符合要求的浏览器必须支持脚本、声明式交互或其他可检测与分发事件的方式,并且必须支持所规定 事件类型 的相关 API。

除需满足所有其他一致性标准外,符合要求的浏览器可为兼容旧内容实现标记为 弃用 的功能,但不建议这样做。

符合要求的浏览器还可支持本规范未涵盖但使用本规范定义的接口、事件或其他特性的功能,并可实现额外接口及相关 事件类型。这些功能可在未来规范中标准化。

未能符合本规范所有必需部分的浏览器不得宣称符合 UI Events。仅部分符合本规范的实现可声明符合相关部分。

符合要求的浏览器还必须是本规范中 IDL 片段的符合实现,详见 Web IDL 规范 [WebIDL]

1.2.2. 创作工具

内容创作工具如其生成的内容使用本规范中定义的 事件类型 且符合规范要求,则视为符合 UI Events。

内容创作工具不得宣称其生成的内容符合 UI Events,若该内容使用了本规范中标记为 弃用 的特性。

符合要求的内容创作工具应为内容作者提供使用所有相关 事件类型 和接口的方式,以适应所创作文档的所有 宿主语言

1.2.3. 内容作者与内容

内容作者如其创作的内容使用本规范规定的 事件类型 且符合规范要求,则视为符合 UI Events。

内容作者不应使用本规范标记为 弃用 的特性,而应采用本规范及其他规范所定义的替代机制。

符合要求的内容必须按照本规范描述的接口及 事件类型 语义进行使用。

建议内容作者遵循 可访问性国际化 指南规范中的最佳实践。

1.2.4. 规范与宿主语言

某规范或宿主语言 如其引用并使用本规范或 [DOM] 中定义的事件流机制、接口、事件或其他特性,且未以不兼容的方式扩展这些特性,则视为符合 UI Events。

某规范或宿主语言 如其引用并使用本文件规定的接口及相关 事件类型,则视为专门符合 UI Events。符合要求的规范可定义额外接口和相关 事件类型,或可以不违背或冲突于本规范相关接口及 事件类型 定义的方式扩展 UI Events 相关内容。

引用 UI Events 的规范或宿主语言 不应使用或推荐本规范标记为 弃用 的特性,而应使用或推荐相关替代机制(如有)。

2. 风格约定

本规范遵循 W3C 规范建议约定, 并补充如下:

此外,本规范中某些术语有特定含义。术语 实现 指实现本规范的浏览器、内容创作工具或其他 用户代理, 而内容作者是指编写脚本或代码、利用规范中描述的接口、方法、属性、事件和其他特性来创建 Web 应用的人员,用户则是指在实现中使用这些 Web 应用的人。

最后:

这是一个备注。

这是一个未解决的问题。

这是一个警告。

interface Example {
    // 这是一个 IDL 定义。
};

3. 基础事件接口

[DOM] 中定义的基础事件接口是 UI Events 的基础。这些基础事件接口在实现中必须始终被支持:

本规范定义的事件类型均派生自上述基础接口,且必须继承其所有属性、方法和常量。

下图描述了本规范所述接口的继承关系结构。

本规范定义的接口继承关系图示
本规范定义的接口继承关系图示

3.1. 事件类型列表

每个事件必须关联一个类型,称为事件类型,可通过事件对象的 type 属性获取。事件类型必须为 DOMString 类型。

根据 DOM 支持级别或用于显示(如屏幕)或交互(如鼠标、键盘、触摸屏或语音)的设备,事件类型可由实现生成。当与 [XML][HTML5] 应用配合使用时,这些语言的规范可能会限制事件类型的语义和作用范围(尤其是可能的 事件目标)。请参阅所用语言的规范以获取这些限制或查找未在本文件中定义的事件类型。

下表为本规范所述事件类型的说明性摘要。

事件类型 同步 / 异步 冒泡阶段 可信事件目标类型 DOM 接口 可取消 默认行为
abort 同步 Window, Element Event
auxclick 同步 Element PointerEvent 视情况而定
beforeinput 同步 Element InputEvent 更新 DOM 元素
blur 同步 Window, Element FocusEvent
click 同步 Element PointerEvent 视情况而定:对于具有激活行为的 目标,执行 激活行为;对于可聚焦 目标,使元素获得焦点。
compositionstart 同步 Element CompositionEvent 显示 文本输入法系统候选窗口
compositionupdate 同步 Element CompositionEvent
compositionend 同步 Element CompositionEvent
contextmenu 同步 Element PointerEvent 如支持则调用上下文菜单
dblclick 同步 Element MouseEvent 视情况而定:对于具有激活行为的 目标,执行 激活行为;对于可聚焦 目标,使元素获得焦点。
error 异步 Window, Element Event
focus 同步 Window, Element FocusEvent
focusin 同步 Window, Element FocusEvent
focusout 同步 Window, Element FocusEvent
input 同步 Element InputEvent
keydown 同步 Element KeyboardEvent 视情况而定:触发 beforeinputinput 事件;启动 文本输入法系统blurfocus 事件;keypress 事件(如支持);激活行为;其他事件
keyup 同步 Element KeyboardEvent
load 异步 Window, Document, Element Event
mousedown 同步 Element MouseEvent 视情况而定:开始拖拽/放置操作;开始文本选择;开始滚动/平移交互(中键配合时,如支持)
mouseenter 同步 Element MouseEvent
mouseleave 同步 Element MouseEvent
mousemove 同步 Element MouseEvent
mouseout 同步 Element MouseEvent
mouseover 同步 Element MouseEvent
mouseup 同步 Element MouseEvent
select 同步 Element Event
unload 同步 Window, Document, Element Event
wheel 异步 Element WheelEvent 滚动(或缩放)文档

关于本规范中弃用事件列表,请见文末附录旧版事件类型

以下是对上表的一种解读方式:load 事件会在 Element 节点的捕获和目标阶段触发为该事件注册的 事件监听器。该事件不可取消。如果为 load 事件在 WindowDocumentElement 节点之外的节点注册事件监听器,或者仅注册在冒泡阶段,则该 事件监听器不会被触发。

不要将上表视为所有列出事件类型的权威说明。例如,load 事件在其他规范中也有应用,如 XMLHttpRequest。同样,dispatchEvent() 可用于向 任何 同样实现了 EventTarget 的对象分发非可信事件。

上述事件类型相关的事件对象包含更多上下文信息——详情请参见 DOM 接口描述。

3.2. 用户界面事件

用户界面事件模块包含与用户界面和文档操作相关的基本事件类型。

3.2.1. UIEvent 接口

在 DOM Level 2 中引入

UIEvent 接口提供了与用户界面事件相关的特定上下文信息。

要创建 UIEvent 接口的实例,可使用 UIEvent 构造函数,并传递可选的 UIEventInit 字典。

对于新定义的事件,不必仅因事件与用户界面相关就继承 UIEvent 接口。仅在 UIEventInit 的成员对这些事件有意义时才继承。

3.2.1.1. UIEvent
[Exposed=Window]
interface UIEvent : Event {
  constructor(DOMString type, optional UIEventInit eventInitDict = {});
  readonly attribute Window? view;
  readonly attribute long detail;
};
UIEvent . view
view 属性用于标识事件生成的 Window

该属性的 未初始化值必须为 null

UIEvent . detail
指定关于该 Event 的一些详细信息,具体取决于事件类型。

该属性的 未初始化值必须为 0

3.2.1.2. UIEventInit
dictionary UIEventInit : EventInit {
  Window? view = null;
  long detail = 0;
};
UIEventInit . view
应初始化为该事件将被分发的全局环境的 Window 对象。如果事件将分发到某元素,则 view 属性应设为包含该元素 ownerDocument 的 Window 对象。
UIEventInit . detail
此值初始化为应用相关的数字。

3.2.2. UIEvent 算法

3.2.2.1. 初始化 UIEvent
输入

event,要初始化的 UIEvent

eventType,包含事件类型的 DOMString

eventTarget,事件的 EventTarget

bubbles,如果该事件可冒泡则为 true

cancelable,如果该事件可取消则为 true

输出

  1. 初始化基础 Event 属性:

    1. 使用 初始化 Event,参数为 eventeventTypebubblescancelable

    2. 设置 event.target = eventTarget

  2. 初始化以下公开属性:

    1. 设置 event.view = eventTarget节点文档Window 对象

    2. 设置 event.detail = 0

  3. 初始化以下历史属性:

    1. 设置 event.which = 0(用于 MouseEventKeyboardEvent

3.2.3. UIEvent 类型

用户界面事件类型如下所列。其中一些事件如果由用户界面生成,则使用 UIEvent 接口,否则使用 Event 接口,具体见各事件说明。

3.2.3.1. load
类型 load
接口 UIEvent (由用户界面生成时),否则为 Event
同步 / 异步 异步
冒泡
可信目标 WindowDocumentElement
可取消
默认行为
上下文
(可信事件)

当 DOM 实现完成资源(如文档)及其任何依赖资源(如图片、样式表或脚本)加载时,用户代理必须分发该事件。未能成功加载的依赖资源不会阻止该事件触发,只要加载它们的资源仍可通过 DOM 访问。如果分发了该事件类型,要求实现至少在 Document 节点上分发该事件。

出于兼容旧版的原因,文档内部资源(如图片)的 load 事件在 HTML 实现中不会包含 Window 于传播路径。更多信息见 [HTML5]

3.2.3.2. unload
类型 unload
接口 UIEvent (由用户界面生成时),否则为 Event
同步 / 异步 同步
冒泡
可信目标 WindowDocumentElement
可取消
默认行为
上下文
(可信事件)

当 DOM 实现从环境中移除资源(如文档)或任何依赖资源(如图片、样式表、脚本)时,用户代理必须分发该事件。该事件类型分发后,文档必须被卸载。如果分发了该事件类型,要求实现至少在 Document 节点上分发该事件。

3.2.3.3. abort
类型 abort
接口 UIEvent (由用户界面生成时),否则为 Event
同步 / 异步 同步
冒泡
可信目标 WindowElement
可取消
默认行为
上下文
(可信事件)

当某资源加载被中止(如用户在加载过程中取消加载),用户代理必须分发该事件。

3.2.3.4. error
类型 error
接口 UIEvent (由用户界面生成时),否则为 Event
同步 / 异步 异步
冒泡
可信目标 WindowElement
可取消
默认行为
上下文
(可信事件)

当某资源加载失败,或已加载但无法根据语义解释(如图片无效、脚本执行错误或 XML 非格式良好),用户代理必须分发该事件。

3.2.3.5. select
类型 select
接口 UIEvent (由用户界面生成时),否则为 Event
同步 / 异步 同步
冒泡
可信目标 Element
可取消
默认行为
上下文
(可信事件)

当用户选择了某些文本后,用户代理必须分发该事件。该事件在选择行为发生后分发。

本规范不提供访问选中文本的上下文信息。适用时,应由 宿主语言定义用户如何选择内容(要考虑国际语言惯例)、select 事件分发的时机,以及内容作者如何访问用户选中的内容。

内容作者要访问用户选中的内容,可使用 宿主语言的原生能力,例如 HTML 编辑 API 的 Document.getSelection() 方法 [Editing]

select 事件未必在所有语言的所有元素上都可用。例如,在 [HTML5] 中,select 事件仅可在表单 inputtextarea 元素上分发。实现可在任何认为合适的上下文分发 select 事件,包括表单控件外的文本选择,或如 SVG 的图像或标记选择。

3.3. 焦点事件

本接口及其相关事件类型与 § 3.3.2 焦点事件顺序 是根据 用户代理可访问性指南 2.0 [UAAG20] 的概念及指引设计的,尤其关注了 焦点机制 及词汇表中关于 focus 的定义。

3.3.1. FocusEvent 接口

本规范中引入

FocusEvent 接口提供了与焦点事件相关的特定上下文信息。

要创建 FocusEvent 接口实例,可使用 FocusEvent 构造函数,并传递可选 FocusEventInit 字典。

3.3.1.1. FocusEvent
[Exposed=Window]
interface FocusEvent : UIEvent {
  constructor(DOMString type, optional FocusEventInit eventInitDict = {});
  readonly attribute EventTarget? relatedTarget;
};
FocusEvent . relatedTarget
用于标识与焦点事件相关的次级 EventTarget,具体取决于事件类型。

出于嵌套浏览上下文的安全考虑,切换到或离开嵌套上下文时,相关 EventTarget 应为 null

该属性的 未初始化值必须为 null

3.3.1.2. FocusEventInit
dictionary FocusEventInit : UIEventInit {
  EventTarget? relatedTarget = null;
};
FocusEventInit . relatedTarget
relatedTarget 应初始化为失去焦点的元素(用于 focusfocusin 事件)或获得焦点的元素(用于 blurfocusout 事件)。

3.3.2. 焦点事件顺序

本规范定义的焦点事件按一定顺序发生。下列为当焦点在元素间切换时的典型事件序列(假设最初没有元素获得焦点):

事件类型 说明
用户切换焦点
1 focus 目标元素首次获得焦点后发送
2 focusin 紧随 focus 事件之后
用户切换焦点
3 blur 目标元素失去焦点后发送
4 focusout 紧随 blur 事件之后
5 focus 第二个目标元素获得焦点后发送
6 focusin 紧随 focus 事件之后

本规范未定义与 focus()blur() 等方法交互时的焦点事件行为,相关行为请见这些方法定义的规范。

3.3.3. 文档焦点与焦点上下文

本事件模块包含用于通知文档 焦点变化的事件类型。相关讨论涉及三种不同的焦点上下文:

本规范定义的事件类型仅处理文档焦点,事件详情中标识的 事件目标必须是窗口内文档或文档的一部分,不能是浏览器或操作系统的一部分,即使是焦点上下文之间切换时也如此。

通常,文档总是有一个获得焦点的元素(即使是文档元素本身),且有持久的 焦点环。在切换焦点上下文时,文档当前获得焦点的元素和焦点环通常保持原状。例如,若文档有三个可获得焦点的元素,第二个被聚焦,用户切换操作系统焦点到其他应用再切回浏览器,第二个元素仍在文档内获得焦点,Tab 键会将焦点切换到第三个元素。宿主语言可以定义哪些元素可以获得焦点、元素可获得焦点的条件、焦点切换的方式及顺序。例如,某些情况下可通过指针悬停获得焦点,其他情况则需鼠标点击。有些元素可能根本不可获得焦点,有些只可通过特定方式(如点击)获得,而不可 Tab 切换。文档可包含多个焦点环。其他规范可以定义比本规范更复杂的焦点模型,包括允许多个元素同时获得当前焦点。

3.3.4. 焦点事件类型

焦点事件类型如下所列。

3.3.4.1. blur
类型 blur
接口 FocusEvent
同步 / 异步 同步
冒泡
可信目标 WindowElement
可取消
是否组合
默认行为
上下文
(可信事件)

当某 用户代理检测到 事件目标失去焦点时,必须分发该事件。必须在该元素失去焦点后再分发本事件类型。该事件类型类似于 focusout,但不冒泡。

3.3.4.2. focus
类型 focus
接口 FocusEvent
同步 / 异步 同步
冒泡
可信目标 WindowElement
可取消
是否组合
默认行为
上下文
(可信事件)

当某 用户代理检测到 事件目标获得焦点时,必须分发该事件。必须在该元素获得焦点后再分发本事件类型。该事件类型类似于 focusin,但不冒泡。

3.3.4.3. focusin
类型 focusin
接口 FocusEvent
同步 / 异步 同步
冒泡
可信目标 WindowElement
可取消
是否组合
默认行为
上下文
(可信事件)

当某 用户代理检测到 事件目标获得焦点时,必须分发该事件。该 事件目标必须是获得焦点的元素。focus 事件必须在本事件分发前触发。该事件类型类似于 focus,但会冒泡。

3.3.4.4. focusout
类型 focusout
接口 FocusEvent
同步 / 异步 同步
冒泡
可信目标 WindowElement
可取消
是否组合
默认行为
上下文
(可信事件)

当某 用户代理检测到 事件目标失去焦点时,必须分发该事件。该 事件目标必须是失去焦点的元素。blur 事件必须在本事件分发前触发。该事件类型类似于 blur,但会冒泡。

3.4. 鼠标事件

鼠标事件模块起源于 [HTML401]onclickondblclickonmousedownonmouseuponmouseoveronmousemoveonmouseout 属性。此事件模块专为指针输入设备(如鼠标或轨迹球)设计。

3.4.1. MouseEvent 接口

在 DOM Level 2 中引入,本规范中有所修改

MouseEvent 接口提供了与鼠标事件相关的特定上下文信息。

在嵌套元素的情况下,鼠标事件总是针对最深层嵌套的元素。

目标元素的祖先可以通过事件冒泡获取其后代元素内发生的鼠标事件通知。

要创建 MouseEvent 接口实例,可使用 MouseEvent 构造函数,并传递可选的 MouseEventInit 字典。

使用 MouseEventinitMouseEvent 初始化对象时,实现可利用 clientXclientY 计算其他坐标(如 DOM Level 0 或其它专有属性暴露的目标坐标,例如 pageX)。

3.4.1.1. MouseEvent
[Exposed=Window]
interface MouseEvent : UIEvent {
  constructor(DOMString type, optional MouseEventInit eventInitDict = {});
  readonly attribute long screenX;
  readonly attribute long screenY;
  readonly attribute long clientX;
  readonly attribute long clientY;
  readonly attribute long layerX;
  readonly attribute long layerY;

  readonly attribute boolean ctrlKey;
  readonly attribute boolean shiftKey;
  readonly attribute boolean altKey;
  readonly attribute boolean metaKey;

  readonly attribute short button;
  readonly attribute unsigned short buttons;

  readonly attribute EventTarget? relatedTarget;

  boolean getModifierState(DOMString keyArg);
};
screenX, 类型为 long, 只读
事件发生时相对于屏幕坐标原点的水平坐标。

该属性的 未初始化值必须为 0

screenY, 类型为 long, 只读
事件发生时相对于屏幕坐标原点的垂直坐标。

该属性的 未初始化值必须为 0

clientX, 类型为 long, 只读
事件发生时相对于事件关联的视口的水平坐标。

该属性的 未初始化值必须为 0

clientY, 类型为 long, 只读
事件发生时相对于事件关联的视口的垂直坐标。

该属性的 未初始化值必须为 0

layerX, 类型为 long, 只读
距离最近的 祖先 元素的水平偏移, 该祖先元素是 堆叠上下文定位元素, 或在 绘制堆叠上下文的定位阶段绘制。

该属性的 未初始化值必须为 0

layerY, 类型为 long, 只读
距离最近的 祖先 元素的垂直偏移, 该祖先元素是 堆叠上下文定位元素, 或在 绘制堆叠上下文的定位阶段绘制。

该属性的 未初始化值必须为 0

ctrlKey, 类型为 boolean, 只读
参见 KeyboardEventctrlKey 属性。

该属性的 未初始化值必须为 false

shiftKey, 类型为 boolean, 只读
参见 KeyboardEventshiftKey 属性。

该属性的 未初始化值必须为 false

altKey, 类型为 boolean, 只读
参见 KeyboardEventaltKey 属性。

该属性的 未初始化值必须为 false

metaKey, 类型为 boolean, 只读
参见 KeyboardEventmetaKey 属性。

该属性的 未初始化值必须为 false

button, 类型为 short, 只读
鼠标事件由鼠标按钮按下或释放引发时,button 必须用于指示哪个指针设备按钮状态发生了变化。

button 属性的值必须如下:

  • 0 表示设备主按钮(一般为左键,或单键设备上的唯一按钮,用于激活控件或选择文本)或未初始化值。

  • 1 表示辅助按钮(一般为中键,常与鼠标滚轮结合使用)。

  • 2 表示次级按钮(一般为右键,常用于显示上下文菜单)。

  • 3 表示 X1(后退)按钮。

  • 4 表示 X2(前进)按钮。

部分指针设备提供或模拟更多按钮状态,超过 2 或小于 0 的值可表示这些按钮。

button 的值不会在非由鼠标按钮按下/释放引发的事件中更新,此时请勿将 0 解释为左键,而应视为未初始化值

某些与 mousedownmouseup 等事件相关的 默认行为 依赖于具体鼠标按钮。

该属性的 未初始化值必须为 0

buttons, 类型为 unsigned short, 只读
在任何鼠标事件中,buttons 必须用于指示当前被按下的鼠标按钮组合,以位掩码表示。

虽然名称类似,buttonsbutton 的值完全不同。buttonmousedown / mouseup 事件处理期间为有效值,buttons 属性则反映任意可信 MouseEvent 对象的鼠标按钮状态(分发期间),包括“无按钮激活”状态(0)。

buttons 属性值必须如下:

  • 0 表示当前无按钮激活。

  • 1 表示设备主按钮(一般为左键,或单键设备上的唯一按钮,用于激活控件或选择文本)。

  • 2 表示次级按钮(一般为右键,常用于显示上下文菜单,如有)。

  • 4 表示辅助按钮(一般为中键,常与鼠标滚轮结合使用)。

部分指针设备提供或模拟更多按钮。要表示这些按钮,值需依次加倍(二进制序列 81632、...)。

任意按钮值组合之和唯一,内容作者可用位操作判断当前被按下的按钮数及具体按钮,适用于任意数量的鼠标按钮。例如 3 表示左键和右键同时按下,5 表示左键和中键同时按下。

某些与 mousedownmouseup 等事件相关的 默认行为 依赖于具体鼠标按钮。

该属性的 未初始化值必须为 0

relatedTarget, 类型为 EventTarget, 只读, 可为 null
用于标识与 UI 事件相关的次级 EventTarget,具体取决于事件类型。

该属性的 未初始化值必须为 null

getModifierState(keyArg)

本规范中引入

使用按键值查询修饰键状态。

如果为修饰键且已激活则返回 true,否则返回 false

DOMString keyArg
参见 KeyboardEventgetModifierState() 方法参数说明。
3.4.1.2. MouseEventInit
dictionary MouseEventInit : EventModifierInit {
  long screenX = 0;
  long screenY = 0;
  long clientX = 0;
  long clientY = 0;

  short button = 0;
  unsigned short buttons = 0;
  EventTarget? relatedTarget = null;
};
screenX, 类型为 long,默认值为 0
初始化 screenX 属性为鼠标指针在用户屏幕上的期望水平相对位置。

将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。

screenY, 类型为 long,默认值为 0
初始化 screenY 属性为鼠标指针在用户屏幕上的期望垂直相对位置。

将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。

clientX, 类型为 long,默认值为 0
初始化 clientX 属性为鼠标指针在用户浏览器客户端窗口的期望水平位置。

将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。

clientY, 类型为 long,默认值为 0
初始化 clientY 属性为鼠标指针在用户浏览器客户端窗口的期望垂直位置。

将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。

button, 类型为 short,默认值为 0
初始化 button 属性为鼠标按钮的期望状态所对应的数字。

数值 0 代表主鼠标按钮,1 代表辅助/中间按钮,2 代表右键。大于 2 的数字也可能出现,但本文档未作规定。

buttons, 类型为 unsigned short,默认值为 0
初始化 buttons 属性为一个数字,表示要视为激活状态的一个或多个鼠标按钮。

buttons 属性为位字段,掩码值为 1 时表示主按钮按下,2 时表示右键按下,4 时表示辅助/中键按下。

在 JavaScript 中,如需初始化 buttons 属性为右键(2)和中键(4)同时按下,可赋值为:
{ buttons: 2 | 4 }

{ buttons: 6 }

relatedTarget, 类型为 EventTarget,可为 null,默认值为 null
relatedTarget 应初始化为鼠标指针刚离开的元素(对于 mouseovermouseenter 事件),或鼠标指针即将进入的元素(对于 mouseoutmouseleavefocusout 事件)。其他事件无需赋值(默认即为 null)。

实现在生成鼠标事件时必须维护 当前点击计数,其必须为非负整数,表示在特定时间内指针设备按钮的连续点击次数。计数重置的延迟取决于环境配置。

3.4.2. 事件修饰符初始化器

MouseEventKeyboardEvent 接口共享一组键盘修饰符属性,并支持检索额外修饰符状态的机制。下述字典允许作者初始化 MouseEventKeyboardEvent 接口的键盘修饰符属性,以及通过 getModifierState() 查询的其他修饰符状态。 使用该字典构造事件的步骤定义在 MouseEvent 构造器小节。

dictionary EventModifierInit : UIEventInit {
  boolean ctrlKey = false;
  boolean shiftKey = false;
  boolean altKey = false;
  boolean metaKey = false;

  boolean modifierAltGraph = false;
  boolean modifierCapsLock = false;
  boolean modifierFn = false;
  boolean modifierFnLock = false;
  boolean modifierHyper = false;
  boolean modifierNumLock = false;
  boolean modifierScrollLock = false;
  boolean modifierSuper = false;
  boolean modifierSymbol = false;
  boolean modifierSymbolLock = false;
};
ctrlKey, 类型为 boolean,默认值为 false
初始化 ctrlKey 属性为 MouseEventKeyboardEvent 对象,如果 Control 键修饰符应视为激活则为 true,否则为 false

true 时,实现还必须初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Control 时返回 true

shiftKey, 类型为 boolean,默认值为 false
初始化 shiftKey 属性为 MouseEventKeyboardEvent 对象,如果 Shift 键修饰符应视为激活则为 true,否则为 false

true 时,实现还必须初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Shift 时返回 true

altKey, 类型为 boolean,默认值为 false
初始化 altKey 属性为 MouseEventKeyboardEvent 对象,如果 Alt(备用)键(或 Option)修饰符应视为激活则为 true,否则为 false

true 时,实现还必须初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Alt 时返回 true

metaKey, 类型为 boolean,默认值为 false
初始化 metaKey 属性为 MouseEventKeyboardEvent 对象,如果 Meta 键修饰符应视为激活则为 true,否则为 false

true 时,实现还必须初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Meta 时返回 true

modifierAltGraph, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 AltGraph 时返回 true
modifierCapsLock, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 CapsLock 时返回 true
modifierFn, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Fn 时返回 true
modifierFnLock, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 FnLock 时返回 true
modifierHyper, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Hyper 时返回 true
modifierNumLock, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 NumLock 时返回 true
modifierScrollLock, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 ScrollLock 时返回 true
modifierSuper, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Super 时返回 true
modifierSymbol, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 Symbol 时返回 true
modifierSymbolLock, 类型为 boolean,默认值为 false
初始化事件对象的键修饰状态,使得调用 getModifierState()getModifierState() 并传入参数 SymbolLock 时返回 true
3.4.2.1. 构造 MouseEvent

通常,当调用 Event 接口或其继承自 Event 接口的构造函数时,应遵循 [DOM] 中描述的步骤。然而 MouseEvent 接口提供了用于初始化 Event 对象键盘修饰符内部状态的额外字典成员,这些状态可通过 getModifierState() 方法查询。本节补充了 DOM4 中初始化新 MouseEvent 对象的相关步骤,以支持这些可选修饰符状态。

在构造 MouseEvent 或使用下述算法从这些对象派生对象时,所有 MouseEvent 及其派生对象都具有可通过 键盘修饰符名称(参见 修饰键列表[UIEvents-Key])设置和获取的 内部键修饰符状态

以下步骤补充了 DOM4 事件构造算法:

3.4.3. MouseEvent 算法

3.4.3.1. 原生操作系统要求

本节的算法假定原生平台操作系统会提供如下能力:

对于上述事件,操作系统能提供如下信息:

3.4.3.2. MouseEvent 全局状态
3.4.3.2.1. 用户代理级状态

UA 必须维护如下全局共享值:

用于追踪鼠标按钮当前状态的 鼠标按钮位掩码

3.4.3.2.2. 窗口级状态

UA 必须维护如下窗口级共享值:

初始值为未定义的 上次鼠标元素,用于记录最近发送 MouseEvent 的 Element

初始为空的 上次鼠标 DOM 路径,包含最近一次发送鼠标事件时 上次鼠标元素 的所有祖先 Element 的快照。

3.4.3.3. MouseEvent 内部状态

MouseEvent 有如下内部标志用于追踪各种修饰键状态:shift 标志control 标志alt 标志altgraph 标志meta 标志。 如果对应修饰键在鼠标事件发生时被按下,则这些标志会被设置。

3.4.3.4. 初始化 MouseEvent
输入

event,要初始化的 MouseEvent

eventType,包含事件类型的 DOMString

eventTarget,事件的 EventTarget

bubbles,如果事件可冒泡则为 true

cancelable,如果事件可取消则为 true

输出

  1. 使用 初始化 UIEvent,参数为 eventeventTypeeventTargetbubblescancelable

  2. 初始化以下公开属性:

    1. 设置 event.screenX 为事件发生位置相对于桌面原点的 x 坐标

    2. 设置 event.screenY 为事件发生位置相对于桌面原点的 y 坐标

    3. 设置 event.clientX 为事件发生位置相对于 视口原点的 x 坐标

    4. 设置 event.clientY 为事件发生位置相对于 视口原点的 y 坐标

    5. 使用 设置鼠标事件修饰符,参数为 event

    6. 设置 event.button = 0

    7. 设置 event.buttons = 鼠标按钮位掩码

  3. 使用 初始化 MouseEvent 的 PointerLock 属性,参数为 event

3.4.3.5. 设置鼠标事件修饰符
输入

event,要更新的 MouseEvent

输出

  1. 如果 键修饰符状态 包含 "Shift",则设置 eventshift 标志,否则取消设置

  2. 如果 键修饰符状态 包含 "Control",则设置 eventcontrol 标志,否则取消设置

  3. 如果 键修饰符状态 包含 "Alt",则设置 eventalt 标志,否则取消设置

  4. 如果 键修饰符状态 包含 "AltGraph",则设置 eventaltgraph 标志,否则取消设置

  5. 如果 键修饰符状态 包含 "Meta",则设置 eventmeta 标志,否则取消设置

  6. 如果 shift 标志 被设置,则 event.shiftKey = true,否则为 false

  7. 如果 control 标志 被设置,则 event.ctrlKey = true,否则为 false

  8. 如果 alt 标志altgraph 标志 被设置,则 event.altKey = true,否则为 false

  9. 如果 meta 标志 被设置,则 event.metaKey = true,否则为 false

3.4.3.6. 创建可取消的 MouseEvent
输入

eventType,包含有效 MouseEvent 类型的 DOMString

eventTarget,事件的 EventTarget

输出

  1. bubbles 为 "true"

  2. cancelable 为 "true"

  3. event = 使用 MouseEvent 创建新事件 的结果

  4. 使用 初始化 MouseEvent,参数为 eventeventTypeeventTargetbubblescancelable

  5. 返回 event

3.4.3.7. 创建不可取消的 MouseEvent
输入

eventType,包含有效 MouseEvent 类型的 DOMString

eventTarget,事件的 EventTarget

输出

  1. bubbles 为 "false"

  2. cancelable 为 "false"

  3. event = 使用 MouseEvent 创建新事件 的结果

  4. 使用 初始化 MouseEvent,参数为 eventeventTypeeventTargetbubblescancelable

  5. 返回 event

3.4.3.8. 计算 MouseEvent button 属性
输入

mbutton,用于识别鼠标按钮的 ID

输出

适用于存储在 MouseEventbutton 属性的按钮 ID

  1. 如果 mbutton 是主鼠标按钮,则返回 0

  2. 如果 mbutton 是辅助(中间)鼠标按钮,则返回 1

  3. 如果 mbutton 是次级鼠标按钮,则返回 2

  4. 如果 mbutton 是 X1(后退)按钮,则返回 3

  5. 如果 mbutton 是 X2(前进)按钮,则返回 4

3.4.3.9. 根据原生事件设置 MouseEvent 属性
输入

event,要初始化的 MouseEvent

native,原生鼠标事件

输出

TODO

  1. 如果 event.type 是 [ mousedown, mouseup ] 之一,则

    1. mbuttonnative 中用于识别按下鼠标按钮的 ID

    2. 设置 event.button = 计算 MouseEvent button 属性,参数为 mbutton

3.4.3.10. 处理原生鼠标按下
输入

native,原生 mousedown

输出

  1. mbuttonnative 中用于识别按下鼠标按钮的 ID

  2. 按如下方式更新 鼠标按钮位掩码

    1. 如果 mbutton 是主鼠标按钮,则设置 0x01 位

    2. 如果 mbutton 是次级鼠标按钮,则设置 0x02 位

    3. 如果 mbutton 是辅助(中间)鼠标按钮,则设置 0x04 位

    其它按钮可从 0x08 开始添加

  3. target = 命中测试,参数为 native 的视口相关坐标

  4. event = 创建可取消的 MouseEvent,参数为 "mousedown"、target

  5. 根据原生事件设置 MouseEvent 属性,参数为 native

  6. 可能发送 pointerdown 事件,参数为 event

  7. result = target 处分发 event

  8. 如果 result 为 true 且 target可聚焦区域 且为 可点击聚焦,则

    1. target 运行 聚焦步骤

  9. 如果 mbutton 是次级鼠标按钮,则

    1. 可能显示上下文菜单,参数为 nativetarget

3.4.3.11. 处理原生鼠标释放
输入

native,原生 mouseup

输出

在 mousedown 和 mouseup 之间可能发生其他鼠标事件。

  1. mbuttonnative 中用于识别按下鼠标按钮的 ID

  2. 按如下方式更新 鼠标按钮位掩码

    1. 如果 mbutton 是主鼠标按钮,则清除 0x01 位

    2. 如果 mbutton 是次级鼠标按钮,则清除 0x02 位

    3. 如果 mbutton 是辅助(中间)鼠标按钮,则清除 0x04 位

  3. target = 命中测试,参数为 native 的视口相关坐标

  4. event = 创建可取消的 MouseEvent,参数为 "mouseup"、target

  5. 根据原生事件设置 MouseEvent 属性,参数为 native

  6. 可能发送 pointerup 事件,参数为 event

  7. target 派发 event

3.4.3.12. 处理原生鼠标点击
输入

native,原生鼠标点击事件

输出

平台应在 处理原生鼠标释放 后立即调用本算法用于生成点击。

  1. target = 命中测试,参数为 native 的视口相关坐标

  2. 发送点击事件,参数为 nativetarget

3.4.3.13. 发送点击事件
输入

native,原生 mousedown

target,事件的 EventTarget

输出

  1. mbutton = 1(默认主鼠标按钮)

  2. 如果 native 有效,则

    1. mbuttonnative 中用于识别按下鼠标按钮的 ID

  3. 如果 mbutton 是主鼠标按钮,则 eventType 为 "click",否则为 "auxclick"

  4. event = 创建 PointerEvent,参数为 eventTypetarget

  5. 如果 native 有效,则

    1. 根据原生事件设置 MouseEvent 属性,参数为 eventnative

    2. 如果 event.screenX 不是整数,则取整

    3. 如果 event.screenY 不是整数,则取整

  6. target 派发 event

参见 pointerevents/100,了解浏览器使用 PointerEvents 及坐标取整的信息。

任何“默认行为”在分发时通过触发目标的 激活行为 算法处理,因此无需在此处理。但需确认现有规范是否处理了 disabled/css-pointer-events/inert/...

要处理 `HTMLelement.click()`,调用本算法时 native = null,target = `HTMLelement`。

要处理键盘触发的点击,调用本算法时 native = null,target = 当前聚焦元素。

3.4.3.14. 处理原生鼠标双击
输入

native,原生鼠标双击事件

输出

本算法应在处理原生鼠标点击后立即调用,用于生成双击事件。

  1. mbuttonnative 中用于识别按下鼠标按钮的 ID

  2. 如果 mbutton 不是主鼠标按钮,则返回

  3. target = 命中测试,参数为 native 的视口相关坐标

  4. event = 创建 PointerEvent,参数为 "dblclick"、target

  5. 根据原生事件设置 MouseEvent 属性,参数为 eventnative

  6. 如果 event.screenX 不是整数,则取整

  7. 如果 event.screenY 不是整数,则取整

  8. target 派发 event

3.4.3.15. 处理原生鼠标移动
输入

native,原生鼠标移动事件

输出

本算法假设 PointerEvents 分发方式,当前规范未明确定义。待 pointerevents/285 解决后可能需更新。

  1. target = 命中测试,参数为 native 的视口相关坐标

  2. targetDomPath = 计算 DOM 路径

  3. 为离开当前元素生成事件:

    1. 如果 上次鼠标元素 已定义且不等于 target,则

      1. mouseout = 创建可取消的 MouseEvent,参数为 "mouseout"、上次鼠标元素

      TODO:用 native 设置 mouseout 属性,含 CSSOM 属性

      1. 可能发送 pointerout 事件,参数为 mouseout

      2. target 派发 mouseout

        验证取消后行为(似乎无影响)。

      3. leaveElements上次鼠标 DOM 路径 的拷贝,去除与 targetDomPath 共有元素。

      4. 遍历 leaveElements 中每个 element

        处理 element 被删除或移动的情况。DOM 变化是否应触发 mouseleave?现在是否发送?是否应丢弃?需验证主流浏览器行为。

        1. mouseleave = 创建不可取消的 MouseEvent,参数为 "mouseleave"、element

        2. 设置 mouseleave.composed = false

          检查兼容性:event.composed 的值。规范为 false。Chrome/Linux = true,Firefox/Linux = false。

        3. 可能发送 pointerleave 事件,参数为 mouseleave

        4. result = element 派发 mouseleave

  4. 为进入新元素生成事件:

    1. 如果 target 不等于 上次鼠标元素,则

      1. mouseover = 创建可取消的 MouseEvent,参数为 "mouseover"、target

      TODO:用 native 设置 mouseout 属性,含 CSSOM 属性

      1. 可能派发 pointerover 事件,使用 mouseover

      2. target 派发 mouseout

        需要验证被取消时的行为(似乎没有影响)。

      3. enterElementstargetDomPath 的副本,去除所有与最近鼠标 DOM 路径相同的元素。

      4. 对于 enterElements 中的每个 element,执行

        处理 element 被删除或移动的情况。

        1. mouseenter = 创建不可取消的 MouseEvent,类型为 "mouseenter",目标为 element

        2. 设置 mouseenter.composed = false

          兼容性检查:event.composed 的值。规范为 false。 Chrome/Linux = true。 Firefox/Linux = false。

        3. 可能派发 pointerenter 事件,使用 mouseenter

        检查 shadow DOM 元素的兼容性。 Chrome/Linux 会在元素和 shadow root 都触发此事件。

        1. result = element 派发 mouseenter

      5. 设置最近鼠标元素target

      6. 设置最近鼠标 DOM 路径targetDomPath

  5. mousemove = 创建可取消的 MouseEvent,类型为 "mousemove",目标为 element

  6. 为 mousemove 设置 PointerLock 属性

  7. 可能派发 pointermove 事件,使用 mousemove

  8. element 派发 mousemove

3.4.3.16. 可能显示上下文菜单
输入

native,原生 mousedown 或 pointer 事件

target,事件的 EventTarget

输出

  1. menuevent = 创建一个 PointerEvent,类型为 "contextmenu",目标为 target

  2. 如果 native 有效,则

    1. 根据 native 设置 MouseEvent 属性 ,使用 native

  3. result = target 派发 menuevent

  4. 如果 result 为 true,则显示 UA 上下文菜单

处理键盘触发的上下文菜单时,调用本算法 native = null,target = 当前聚焦元素。

3.4.4. 鼠标事件顺序

本规范定义的某些鼠标事件必须以特定顺序发生。下表展示了当指针设备的光标移入某元素时必须发生的事件序列:

事件类型 元素 备注
1 mousemove
指针设备移动到元素A内……
2 mouseover A
3 mouseenter A
4 mousemove A 多次 mousemove 事件
指针设备移出元素A……
5 mouseout A
6 mouseleave A

当指针设备进入元素 A,再进入嵌套的元素 B,再移出时,必须依次发生以下事件:

事件类型 元素 备注
1 mousemove
指针设备移入元素A……
2 mouseover A
3 mouseenter A
4 mousemove A 多次 mousemove 事件
指针设备移入嵌套元素B……
5 mouseout A
6 mouseover B
7 mouseenter B
8 mousemove B 多次 mousemove 事件
指针设备从元素B移回A……
9 mouseout B
10 mouseleave B
11 mouseover A
12 mousemove A 多次 mousemove 事件
指针设备移出元素A……
13 mouseout A
14 mouseleave A

有时元素可以通过CSS设置视觉重叠。如下例,A、B、C三个元素在页面上尺寸和绝对位置完全重合,C是B的子元素,B是A的子元素:

三个堆叠在一起的元素的图形示意。底层为A,顶层为C
三个元素完全堆叠的图形示意,指针设备在堆叠区域上移动。

当指针设备从堆叠外部移入标记为C的最顶层元素后再移出,必须按以下事件序列发生:

事件类型 元素 备注
1 mousemove
指针设备移入堆叠最顶层元素C
2 mouseover C
3 mouseenter A
4 mouseenter B
5 mouseenter C
6 mousemove C 多次 mousemove 事件
指针设备移出元素C……
7 mouseout C
8 mouseleave C
9 mouseleave B
10 mouseleave A

mouseover/mouseout 事件仅触发一次,而 mouseenter/mouseleave 事件会触发三次(分别针对每个元素)。

指针设备(如鼠标或触控板)上的按钮在某元素上按下与释放时,典型的事件顺序如下:

事件类型 备注
1 mousedown
2 mousemove 可选,多次事件,有一定限制
3 mouseup
4 click
5 mousemove 可选,多次事件,有一定限制
6 mousedown
7 mousemove 可选,多次事件,有一定限制
8 mouseup
9 click
10 dblclick

mousedownmouseup 事件之间允许的 mousemove 事件的延迟、幅度、距离和数量由实现、设备和平台决定。这种容差有助于手部不稳等身体障碍用户更好地操作指针设备。

每个实现会自行决定合适的滞后容差,但一般情况下,当相关的mousedownmouseup事件的事件目标为同一元素,且中间没有mouseoutmouseleave事件时,应该触发clickdblclick事件;而当相关的mousedownmouseup事件目标不同,则应该在最近的共同包含祖先元素上触发clickdblclick事件。

如果 mousedown 事件目标是HTML文档的 body 元素,而对应的 mouseup 事件目标是 根元素,则 click 事件会在 根元素 上分发,因为它是最近的公共包含祖先。

如果 事件目标(例如目标元素)在鼠标事件序列期间被从DOM中移除,则剩余事件不得在该元素上触发。

如果目标元素在 mousedown 事件后被移除,则不会在该元素上分发 mouseupclickdblclick,也不会有默认激活事件。但 mouseup 事件仍会在移除后暴露给鼠标的元素上分发。同理,如果目标元素在 mouseup 事件分发期间被移除,则 click 及后续事件不会分发。

3.4.5. 鼠标事件类型

鼠标事件类型如下所列。在嵌套元素的情况下,鼠标事件类型总是会以最深层嵌套的元素为目标。目标元素的祖先可以通过冒泡机制获取其后代元素内发生的鼠标事件通知。

3.4.5.1. auxclick
类型 auxclick
接口 PointerEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为 视情况而定
上下文
(可信事件)

auxclick 事件类型必须在指针指向的最顶层事件目标上分发,当用户按下并释放非主指针按钮,或以模拟该操作的方式激活指针时。鼠标按钮的激活方式取决于指针设备和环境配置,例如可能依赖于屏幕位置或按下与释放之间的延迟。

auxclick 事件仅应针对非主指针按钮触发(即 button 值不为 0buttons 值大于 1)。主按钮(如标准鼠标左键)不得触发 auxclick 事件。相关主按钮事件请参见 click

auxclick 事件在同一元素上可能会被 mousedownmouseup 事件先于其分发,忽略节点类型变化(如文本节点)。根据环境配置,auxclick 事件在指针按钮按下与释放之间,若发生 mouseovermousemovemouseout 类型之一或多个事件,也可能会分发。

auxclick 事件类型的默认行为依赖于事件的事件目标以及 buttonbuttons 属性的值。典型的默认行为如下:

处理中键 auxclick 事件。
myLink.addEventListener("auxclick", function(e) { if (e.button === 1) { // 这将阻止默认行为,比如中键点击链接时打开新标签页。 e.preventDefault(); // 在此处处理中键点击,比如自定义打开链接或按钮到新标签页,或做其它操作。 // 例如标签栏的关闭操作等也可在这里做。 } });

右键情况下,auxclick 事件在 contextmenu 事件之后分发。注意有些用户代理在显示上下文菜单时会屏蔽所有输入事件,因此 auxclick 在此场景下可能不可用。更多说明参见 此示例

处理右键 auxclick 事件
myDiv.addEventListener("contextmenu", function(e) { // 阻止显示默认上下文菜单,保证页面能收到事件。 e.preventDefault(); }); myDiv.addEventListener("auxclick", function(e) { if (e.button === 2) { // 在此处处理右键点击,比如弹出自定义上下文菜单。 } });

3.4.5.2. click
类型 click
接口 PointerEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为 视情况而定
上下文
(可信事件)

click 事件类型必须在指针指向的最顶层事件目标上分发,当用户按下并释放主指针按钮,或以模拟该操作的方式激活指针时。鼠标按钮的激活方式取决于指针设备和环境配置,例如可能依赖于屏幕位置或按下与释放之间的延迟。

click 事件只应针对主指针按钮触发(即 button 值为 0buttons 值为 1)。次级按钮(如标准鼠标的中键或右键)不得触发 click 事件。相关非主按钮事件请参见 auxclick

click 事件可能会被 mousedownmouseup 事件先于其分发,忽略节点类型变化(如文本节点)。根据环境配置,click 事件在指针按钮按下与释放之间发生 mouseovermousemovemouseout 类型之一或多个事件时,也可能会分发。click 事件之后也可能会跟随 dblclick 事件。

如果用户在一个设置了较大 line-height 的 <p> 元素的文本节点上按下鼠标,然后略微移动鼠标使指针不再位于文本节点但仍在该 <p> 元素的块内(即指针在相同行块间但未在文本节点本身上),随后松开鼠标,则仍会触发 click 事件(只要在正常的 迟滞范围内),因为用户始终在同一元素范围内。注意 UA 生成的鼠标事件不会分发到文本节点。

除了与指针设备相关,click 事件类型还必须作为元素激活的一部分进行分发。

为最大化可访问性,内容作者建议在自定义控件定义激活行为时优先使用 click 事件类型,而不是 mousedownmouseup 等更依赖设备的事件。尽管 click 事件类型起源于指针设备(如鼠标),但后续实现已扩展其为设备无关的元素激活事件类型。

click 事件类型的默认行为依赖于事件的事件目标以及 buttonbuttons 属性的值。典型的默认行为如下:

3.4.5.3. contextmenu
类型 contextmenu
接口 PointerEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为 如果支持则调用上下文菜单。
上下文
(可信事件)

用户代理必须在调用上下文菜单前分发此事件。

contextmenu 事件由鼠标右键触发时,contextmenu 事件必须在 mousedown 事件后分发。

根据平台不同,contextmenu 事件可能在 mouseup 事件之前或之后分发。

3.4.5.4. 双击(dblclick)
类型 dblclick
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
组合
默认行为
上下文
(可信事件)

当指针设备的主按钮在某个元素上被点击两次时,用户代理必须分派此事件。 双击的定义取决于环境配置,但事件目标在 mousedownmouseupdblclick 之间必须相同。 如果单击和双击同时发生,则此事件类型必须在事件类型 click 之后分派,否则在事件类型 mouseup 之后分派。

click 事件类似,dblclick 事件只应为主指针按钮触发。 次要按钮不得触发 dblclick 事件。

取消 click 事件不会影响 dblclick 事件的触发。

click 事件类型一样,默认行为会根据事件的 事件目标buttonbuttons 属性的值而变化。dblclick 事件类型的典型默认行为click 事件类型一致。

3.4.5.5. mousedown
类型 mousedown
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为 视情况而定:开始拖放操作;开始文本选择;开始滚动/平移交互(若支持与中键配合)
上下文
(可信事件)

用户代理必须在指针设备按钮在某元素上按下时分发此事件。

许多实现会使用 mousedown 事件开始多种依赖上下文的默认行为。如果此事件被取消,这些默认行为可以被阻止。这些默认行为包括:开始对图片或链接进行拖放交互、开始文本选择等。同时,部分实现支持鼠标驱动的平移功能,在 mousedown 事件分发时按下中键可激活此功能。

3.4.5.6. mouseenter
类型 mouseenter
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在指针设备进入某元素或其后代元素边界时分发此事件。用户代理还必须在元素或其后代移到主指针设备下方时分发此事件。此事件类型类似于 mouseover,但它不会冒泡,且指针设备从元素进入其后代元素边界时不得分发。

此事件类型与 CSS :hover 伪类有相似之处。另请参阅 mouseleave 事件类型。

3.4.5.7. mouseleave
类型 mouseleave
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在指针设备离开某元素及其所有后代元素边界时分发此事件。用户代理还必须在元素或其后代不再位于主指针设备下方时分发此事件。此事件类型类似于 mouseout,但它不会冒泡,且只有指针设备离开元素及其所有子元素边界时才分发。

此事件类型与 CSS :hover 伪类有相似之处。另请参阅 mouseenter 事件类型。

3.4.5.8. mousemove
类型 mousemove
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在指针设备位于某元素上移动时分发此事件。指针设备移动时事件的触发频率依赖于实现、设备和平台,但对于持续的指针设备移动,应连续触发多个 mousemove 事件,而不是每次鼠标移动只触发一个事件。鼓励实现根据响应性与性能平衡确定最佳事件频率。

在某些实现环境(如浏览器)中,当用户开始拖动操作(如按下鼠标按钮)并且指针设备已离开用户代理边界时,mousemove 事件仍可能持续触发。

此事件在 DOM Level 2 Events 规范中曾被指定为不可取消,但后来因用户代理间的互操作性而更改为可取消。

3.4.5.9. mouseout
类型 mouseout
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在指针设备离开某元素边界或元素不再位于主指针设备下方时分发此事件。此事件类型类似于 mouseleave,但不同点在于它会冒泡,并且必须在指针设备从元素进入其后代元素边界时分发。

另请参阅 mouseover 事件类型。

3.4.5.10. mouseover
类型 mouseover
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在指针设备进入某元素边界或元素移动到主指针设备下方时分发此事件。此事件类型类似于 mouseenter,但不同点在于它会冒泡,且指针设备进入某元素边界时必须分发,即使该元素的祖先是同一事件目标,并且使用同一事件监听器实例。

另请参阅 mouseout 事件类型。

3.4.5.11. mouseup
类型 mouseup
接口 MouseEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在指针设备按钮在某元素上释放时分发此事件。

在某些实现环境(如浏览器)中,即使指针设备已离开用户代理边界(如用户在按下鼠标按钮时开始拖动操作),也可以分发 mouseup 事件。

3.5. 滚轮事件

滚轮是一种可以在一个或多个空间维度上旋转的设备,可以与指针设备相关联。坐标系统取决于环境配置。

用户环境可能配置为将垂直滚动与y轴旋转相关联,水平滚动与x轴旋转相关联,缩放与z轴旋转相关联。

WheelEvent 对象的 deltaX、deltaY 和 deltaZ 属性表示沿各自轴的测量值,单位为像素、行或页。实际测量值是经过环境特定算法,将滚轮设备的实际旋转/移动转换为适当的值和单位后得到的。

用户环境设置可以自定义对滚轮设备实际旋转/移动的解释。例如,常见的有齿鼠标滚轮一次滚动可以产生162像素的测量(162只是示例值,实际值取决于用户代理的当前屏幕尺寸)。用户可以更改默认环境设置来加快鼠标滚轮速度,从而增加此数值。此外,部分鼠标滚轮软件支持加速(滚轮旋转越快,每次测量的 delta 越大),甚至支持亚像素旋转测量。因此,作者不能假定在一个用户代理中的某个旋转量会在所有用户代理中产生相同的delta值。

deltaX、deltaY 和 deltaZ 属性的符号(正或负)在多次分发 wheel 事件且实际滚轮设备旋转/移动方向一致时必须保持一致。如果用户代理将滚轮事件的默认行为设为滚动,则delta的符号应遵循右手坐标系:正的X、Y、Z轴分别指向文档的最右边、最下边和最远端(远离用户)。

各个用户代理(视环境和硬件配置而定)可能对同一物理滚轮操作有不同解释。例如,在触控板边缘从上到下进行一次垂直滑动可以被解释为向下滚动页面或向上平移页面(即分别导致正或负的 deltaY 值)。

用户代理在首次触发滚轮事件时,必须创建一次滚轮事件事务,以便在实现定义的时间范围内的所有后续滚轮事件都能定位到同一元素。滚轮事件事务是一系列与单个用户操作相关联的滚轮事件。该滚轮事件事务必须具有与首次滚轮事件发生时的最顶层事件目标相关联的事件目标。

在可滚动元素中定位的一系列滚轮事件可能是从子元素上方开始的,同一次用户操作的后续事件可能会发生在子元素上。

3.5.1. WheelEvent 接口

本规范中引入

WheelEvent 接口提供了与 wheel 事件相关的特定上下文信息。

要创建 WheelEvent 接口实例,请使用 WheelEvent 构造函数,并传递可选的 WheelEventInit 字典参数。

3.5.1.1. WheelEvent
[Exposed=Window]
interface WheelEvent : MouseEvent {
  constructor(DOMString type, optional WheelEventInit eventInitDict = {});
  // DeltaModeCode
  const unsigned long DOM_DELTA_PIXEL = 0x00;
  const unsigned long DOM_DELTA_LINE  = 0x01;
  const unsigned long DOM_DELTA_PAGE  = 0x02;

  readonly attribute double deltaX;
  readonly attribute double deltaY;
  readonly attribute double deltaZ;
  readonly attribute unsigned long deltaMode;
};
DOM_DELTA_PIXEL
delta 的单位必须为像素。这是大多数操作系统和实现配置下最常见的情况。
DOM_DELTA_LINE
delta 的单位必须为文本行。许多表单控件采用此方式。
DOM_DELTA_PAGE
delta 的单位必须为页面,可以定义为单个屏幕或标记的页面。
deltaX, 类型为 double,只读
在默认行为为滚动的用户代理中,值必须为事件未取消时沿x轴滚动的测量值(单位为像素、行或页)。否则,该值为实现特定的滚轮设备围绕x轴移动的测量值(单位为像素、行或页)。

此属性的未初始化值必须为0.0

deltaY, 类型为 double,只读
在默认行为为滚动的用户代理中,值必须为事件未取消时沿y轴滚动的测量值(单位为像素、行或页)。否则,该值为实现特定的滚轮设备围绕y轴移动的测量值(单位为像素、行或页)。

此属性的未初始化值必须为0.0

deltaZ, 类型为 double,只读
在默认行为为滚动的用户代理中,值必须为事件未取消时沿z轴滚动的测量值(单位为像素、行或页)。否则,该值为实现特定的滚轮设备围绕z轴移动的测量值(单位为像素、行或页)。

此属性的未初始化值必须为0.0

deltaMode, 类型为 unsigned long,只读
deltaMode 属性包含 delta 值的单位指示。默认值为 DOM_DELTA_PIXEL(像素)。

此属性必须设置为 DOM_DELTA 常量之一,用于指示 delta 值的单位。具体测量依赖于设备、操作系统和应用配置。

此属性的未初始化值必须为0

3.5.1.2. WheelEventInit
dictionary WheelEventInit : MouseEventInit {
  double deltaX = 0.0;
  double deltaY = 0.0;
  double deltaZ = 0.0;
  unsigned long deltaMode = 0;
};
deltaX, 类型为 double,默认值为 0.0
参见 deltaZ 属性。
deltaY, 类型为 double,默认值为 0.0
参见 deltaZ 属性。
deltaZ, 类型为 double,默认值为 0.0
初始化 deltaZ 属性。此属性(以及 deltaXdeltaY)的正值采用右手坐标系:X、Y、Z 轴分别指向文档最右、最下和最远(远离用户)。负值则为相反方向。
deltaMode, 类型为 unsigned long,默认值为 0
初始化 deltaMode 属性,枚举值为 0、1 或 2,分别表示滚动的像素量(DOM_DELTA_PIXEL)、行数(DOM_DELTA_LINE)或页数(DOM_DELTA_PAGE),如果滚轮旋转会导致滚动。

3.5.2. 滚轮事件类型

3.5.2.1. wheel
类型 wheel
接口 WheelEvent
同步 / 异步 异步
冒泡
可信目标 Element
可取消 视情况而定
可组合
默认行为 滚动(或缩放)文档
上下文
(可信事件)

用户代理必须在鼠标滚轮围绕任一轴旋转,或等效输入设备(如鼠标球、某些平板或触控板等)模拟此操作时分发此事件。根据平台和输入设备,斜向滚轮delta可能以单个包含多个非零轴的 wheel 事件形式,或为每个非零轴分别分发多个 wheel事件。

wheel 事件类型的典型默认行为是按指示的数量滚动(或在某些情况下缩放)文档。如果此事件被取消,实现不得滚动或缩放文档(或执行与此事件类型相关的其它实现特定默认行为)。

在某些用户代理或某些输入设备中,滚轮旋转速度会影响delta值,旋转速度越快,delta值越大。

3.5.2.2. 滚轮事件的可取消性

在滚轮事件上调用 preventDefault 可以阻止或中断滚动。为了获得最佳滚动性能,用户代理可能不会等待与滚动相关的每个滚轮事件都处理完毕再判断是否被取消。在这种情况下,用户代理应生成 cancelable 属性为 falsewheel 事件,表示无法使用 preventDefault 来阻止或中断滚动。否则 cancelable 将为 true

特别地,如果用户代理检测到没有非被动监听器,则只应生成不可取消的 wheel 事件。

3.6. 输入事件

输入事件是在 DOM 因用户操作(例如在可编辑区域键盘输入、删除或格式化文本等)直接更新或即将更新时发送的通知。

3.6.1. InputEvent 接口

3.6.1.1. InputEvent

在 DOM Level 3 中引入

[Exposed=Window]
interface InputEvent : UIEvent {
  constructor(DOMString type, optional InputEventInit eventInitDict = {});
  readonly attribute USVString? data;
  readonly attribute boolean isComposing;
  readonly attribute DOMString inputType;
};
data, 类型为 USVString,只读,可为 null
data 保存由输入法生成的字符值。它可以是一个 Unicode 字符或一个非空的 Unicode 字符序列 [Unicode]。字符应按照 Unicode 规范中的 NFC 归一化形式进行归一化,定义见 [UAX15]。 此属性可以包含空字符串

此属性的未初始化值必须为 null

isComposing, 类型为 boolean,只读
如果输入事件是在一个组合会话期间发生(即在 compositionstart 事件之后、对应的 compositionend 事件之前),则为 true,否则为 false

此属性的未初始化值必须为 false

inputType, 类型为 DOMString,只读
inputType 包含一个字符串,用来标识与事件相关的输入类型。

有效值列表参见 [Input-Events] 规范。

此属性的未初始化值必须为 空字符串 ""

3.6.1.2. InputEventInit
dictionary InputEventInit : UIEventInit {
  DOMString? data = null;
  boolean isComposing = false;
  DOMString inputType = "";
};
data, 类型为 DOMString,可为 null,默认值为 null
初始化 InputEvent 对象的 data 属性。
isComposing, 类型为 boolean,默认值为 false
初始化 InputEvent 对象的 isComposing 属性。
inputType, 类型为 DOMString,默认值为 ""
初始化 InputEvent 对象的 inputType 属性。

3.6.2. 输入事件顺序

本规范定义的输入事件必须按照特定顺序发生。

事件类型 备注
1 beforeinput
DOM 元素已更新
2 input

3.6.3. 输入事件类型

3.6.3.1. beforeinput
类型 beforeinput
接口 InputEvent
同步 / 异步 同步
冒泡
可信目标 Element(具体如 HTMLInputElement 控件类型等)或启用 contenteditable 属性的任意 Element
可取消
可组合
默认行为 更新 DOM 元素
上下文
(可信事件)

用户代理必须在 DOM 即将更新时分发此事件。

3.6.3.2. input
类型 input
接口 InputEvent
同步 / 异步 同步
冒泡
可信目标 Element(具体如 HTMLInputElement 控件类型等)或启用 contenteditable 属性的任意 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在 DOM 更新后立即分发此事件。

3.7. 键盘事件

键盘事件是依赖于设备的,即它们依赖于输入设备的能力以及在操作系统中的映射方式。详情请参阅键盘事件和按键值,其中包括键盘事件与组合事件结合使用的示例。根据字符生成设备,可能不会生成键盘事件。

键盘事件只是提供文本输入的一种方式。在编辑场景下,也可以考虑使用 InputEvent 作为键盘事件的替代或补充。

3.7.1. KeyboardEvent 接口

本规范中引入

KeyboardEvent 接口提供与键盘设备相关的特定上下文信息。每个键盘事件都通过一个值引用一个按键。键盘事件通常会发送到拥有焦点的元素。

KeyboardEvent 接口为一些常用修饰键提供了便捷属性:ctrlKeyshiftKeyaltKeymetaKey。 这些属性等同于使用 getModifierState() 方法,并分别传入 ControlShiftAltMeta

要创建 KeyboardEvent 接口实例,请使用 KeyboardEvent 构造函数,并传递可选的 KeyboardEventInit 字典参数。

3.7.1.1. KeyboardEvent
[Exposed=Window]
interface KeyboardEvent : UIEvent {
  constructor(DOMString type, optional KeyboardEventInit eventInitDict = {});
  // KeyLocationCode
  const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00;
  const unsigned long DOM_KEY_LOCATION_LEFT = 0x01;
  const unsigned long DOM_KEY_LOCATION_RIGHT = 0x02;
  const unsigned long DOM_KEY_LOCATION_NUMPAD = 0x03;

  readonly attribute DOMString key;
  readonly attribute DOMString code;
  readonly attribute unsigned long location;

  readonly attribute boolean ctrlKey;
  readonly attribute boolean shiftKey;
  readonly attribute boolean altKey;
  readonly attribute boolean metaKey;

  readonly attribute boolean repeat;
  readonly attribute boolean isComposing;

  boolean getModifierState(DOMString keyArg);
};
DOM_KEY_LOCATION_STANDARD
按键激活不能区分为左侧或右侧版本,也不是来自数字小键盘(除了 NumLock 键),也不是来自与数字小键盘对应的虚拟键。

PC 101键美国键盘上的 Q 键。
PC 101键美国键盘上的 NumLock 键。
PC 101键美国键盘主区上的 1 键。

DOM_KEY_LOCATION_LEFT
按键激活来自于左侧按键位置(当该键有多个可能位置时)。

PC 101键美国键盘上的左侧 Control 键。

DOM_KEY_LOCATION_RIGHT
按键激活来自于右侧按键位置(当该键有多个可能位置时)。

PC 101键美国键盘上的右侧 Shift 键。

DOM_KEY_LOCATION_NUMPAD
按键激活来自数字小键盘或与数字小键盘对应的虚拟键(当该键有多个可能位置时)。注意 NumLock 键应始终编码为 locationDOM_KEY_LOCATION_STANDARD

PC 101键美国键盘数字键区上的 1 键。

key, 类型为 DOMString,只读
key 保存与按下的按键对应的key 属性值

key 属性与传统的 keyCode 属性无关,并且取值集合也不同。

此属性的未初始化值必须为 ""(空字符串)。

code, 类型为 DOMString,只读
code 保存识别被按下物理按键的字符串。该值不受当前键盘布局或修饰键状态的影响,因此某个按键总是返回相同的值。

此属性的未初始化值必须为 ""(空字符串)。

location, 类型为 unsigned long,只读
location 属性表示按键在设备上的逻辑位置。

此属性必须设置为 DOM_KEY_LOCATION 常量之一,以指示设备上的按键位置。

如果用户代理允许按键重映射,则重映射按键的 location 值必须设置为新按键适用的值。例如,如果 "ControlLeft" 键被映射为 "KeyQ" 键, 则 location 属性必须设置为 DOM_KEY_LOCATION_STANDARD。 反之,如果 "KeyQ" 键被重映射到某个 Control 键, 则 location 属性必须设置为 DOM_KEY_LOCATION_LEFTDOM_KEY_LOCATION_RIGHT

此属性的未初始化值必须为 0

ctrlKey, 类型为 boolean,只读
如果 Control(控制)修饰键激活,则为 true

此属性的未初始化值必须为 false

shiftKey, 类型为 boolean,只读
如果 Shift 修饰键激活,则为 true

此属性的未初始化值必须为 false

altKey, 类型为 boolean,只读
如果 Alt(替代/Option)修饰键激活,则为 true

此属性的未初始化值必须为 false

metaKey, 类型为 boolean,只读
如果 Meta 修饰键激活,则为 true

在 Mac 系统上,"Command""⌘")修饰键由该属性表示。

此属性的未初始化值必须为 false

repeat, 类型为 boolean,只读
当按键被持续按下时为 true。持续按下某键时,必须按照系统配置的速率重复触发 keydownbeforeinputinput 事件。对于具有长按行为的移动设备,首个 repeat 属性值为 true 的按键事件必须视为长按指示。开始重复所需的按键持续时间取决于配置。

此属性的未初始化值必须为 false

isComposing, 类型为 boolean,只读
如果按键事件发生在组合会话期间,即在 compositionstart 事件之后、对应的 compositionend 事件之前,则为 true

此属性的未初始化值必须为 false

getModifierState(keyArg)
使用按键值查询修饰键状态。

如果是修饰键且处于激活状态则返回 true,否则为 false

DOMString keyArg
修饰键值。合法的修饰键定义见修饰键表[UIEvents-Key]

如果应用希望区分左右修饰键,可以通过键盘事件和 location 判断。

3.7.1.2. KeyboardEventInit
dictionary KeyboardEventInit : EventModifierInit {
  DOMString key = "";
  DOMString code = "";
  unsigned long location = 0;
  boolean repeat = false;
  boolean isComposing = false;
};
key, 类型为 DOMString,默认值为 ""
初始化 KeyboardEvent 对象的 key 属性为表示按键含义的 Unicode 字符串(考虑所有键盘修饰键,如 shift 状态)。该值为最终有效值。如果按键不是可打印字符,则应为 [UIEvents-Key] 中定义的按键值之一。
code, 类型为 DOMString,默认值为 ""
初始化 KeyboardEvent 对象的 code 属性为表示按下按键的 Unicode 字符串,忽略键盘布局等修饰。该值应为 [UIEvents-Code] 中定义的代码值之一。
location, 类型为 unsigned long,默认值为 0
初始化 KeyboardEvent 对象的 location 属性为如下位置数值常量之一:
repeat, 类型为 boolean,默认值为 false
初始化 KeyboardEvent 对象的 repeat 属性。当前 KeyboardEvent 被认为是由于单个按键长按导致的重复事件序列时应为 true,否则为 false
isComposing, 类型为 boolean,默认值为 false
初始化 KeyboardEvent 对象的 isComposing 属性。若事件发生在组合序列期间则为 true,否则为 false
传统键盘事件实现包含三个附加属性:keyCodecharCodewhichkeyCode 表示与计算机键盘上某个特定按键关联的数值,charCode 表示与该按键关联的字符的 ASCII 值(可能与 keyCode 相同),仅适用于能产生字符值的按键。

实际上,keyCodecharCode 在不同平台甚至同一实现的不同操作系统或本地化下都不一致。规范不定义 keyCodecharCode 的取值或行为。符合规范的 UI Events 实现中,内容作者应使用 keycode

更多信息参见关于传统按键属性的附录。

为兼容现有内容,虚拟键盘(如屏幕输入设备上的软件键盘)应生成正常范围的键盘事件,即使它们没有物理按键。

在某些实现或系统配置下,部分按键事件或其值可能会被正在使用的输入法抑制。

3.7.2. 键盘事件按键位置

location 属性可用于区分由键盘上不同物理按键生成的 key 值,例如左右 Shift 键或物理方向键与数字键盘方向键(NumLock 关闭时)。

下表定义了键盘上具有多个位置的特殊按键的有效 location 取值:

KeyboardEvent . key 有效 location 取值
"Shift", "Control", "Alt", "Meta" DOM_KEY_LOCATION_LEFT, DOM_KEY_LOCATION_RIGHT
"ArrowDown", "ArrowLeft", "ArrowRight", "ArrowUp" DOM_KEY_LOCATION_STANDARD, DOM_KEY_LOCATION_NUMPAD
"End", "Home", "PageDown", "PageUp" DOM_KEY_LOCATION_STANDARD, DOM_KEY_LOCATION_NUMPAD
"0", "1", "2", "2", "4", "5", "6", "7", "8", "9", ".", "Enter", "+", "-", "*", "/" DOM_KEY_LOCATION_STANDARD, DOM_KEY_LOCATION_NUMPAD

对于未在表中列出的所有其它按键,location 属性必须始终设置为 DOM_KEY_LOCATION_STANDARD

3.7.3. KeyboardEvent 算法

3.7.3.1. KeyboardEvent 的全局状态
3.7.3.1.1. 用户代理级状态

UA 必须维护以下用于整个用户代理的共享值。

一个 按键修饰状态 (初始为空),用于记录系统上每个修饰键的当前状态。

3.7.4. 键盘事件顺序

本规范定义的键盘事件针对任意按键按如下固定顺序发生:

事件类型 备注
1 keydown
2 beforeinput (仅限会产生字符值的按键)
与此按键相关的任何默认行为,如向 DOM 插入字符。
3 input (仅限已更新 DOM 的按键)
作为持续按住按键的结果产生的任何事件(见下文)。
4 keyup

如果按键被持续按下,则以下事件可能会以依赖环境的速率重复:

事件类型 备注
1 keydown repeat 属性为 true
2 beforeinput (仅限会产生字符值的按键)
与此按键相关的任何默认行为,如向 DOM 插入字符。
3 input (仅限已更新 DOM 的按键)

通常,与某个按键关联的默认行为会在 keyup 事件分发前完成。这可能会使 keyup 事件略有延迟(但一般不可察觉)。

按键事件的事件目标为当前聚焦并处理键盘操作的元素。通常为 HTML input 元素或可编辑文本元素,但也可以是宿主语言定义用于接受键盘输入(如激活快捷键或触发其他行为)的元素。如果没有合适的元素获得焦点,事件目标将为 HTML body 元素(如可用),否则为根元素

事件目标在不同键盘事件间可能发生变化。例如,keydown 事件针对 Tab 键时,事件目标可能与同一次击键的 keyup 事件不同。

3.7.5. 键盘事件类型

3.7.5.1. keydown
类型 keydown
接口 KeyboardEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为 视情况而定:beforeinputinput 事件;启动文本输入法系统blurfocus 事件;keypress 事件(如支持);激活行为;其他事件
上下文
(可信事件)

用户代理必须在按下按键时分发此事件。keydown 事件类型依赖设备,取决于输入设备的能力及其在操作系统中的映射。该事件类型必须在按键映射之后生成,并且必须在与同一按键相关的 beforeinputinputkeyup 事件之前分发。

keydown 事件的默认行为取决于按键:

如果该事件被取消,则相关事件类型不得分发,相关操作也不得执行。

keydownkeyup 事件传统上用于检测任意按键,而不仅是那些能产生字符值的按键。

3.7.5.2. keyup
类型 keyup
接口 KeyboardEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在按键释放时分发此事件。keyup 事件类型依赖设备,取决于输入设备的能力及其在操作系统中的映射。该事件类型必须在按键映射之后生成,并且必须在与同一按键相关的 keydownbeforeinputinput 事件之后分发。

keydownkeyup 事件传统上用于检测任意按键,而不仅是那些能产生字符值的按键。

3.8. 组合事件

组合事件提供了除键盘事件之外的补充或替代文本输入方式,以支持输入键盘上不常见的字符。例如,组合事件可以用于在标准美式键盘上为字符添加重音符号,构建亚洲多字母语言的字形(通过基础部件或类别),在移动设备键盘上通过组合按键选择词语,或通过语音识别处理器将语音命令转换为文本。有关组合事件与键盘事件结合使用的示例,请参阅 § 4 键盘事件和按键值

从概念上讲,一个组合会话包括一个 compositionstart 事件、一个或多个 compositionupdate 事件,以及一个 compositionend 事件,在每次会话的每个“阶段”之间,data 属性的值会持续存在。

注意: 当组合会话处于活动状态时,如果输入设备为键盘,则仍会向 DOM 派发键盘事件。详细顺序见 compositionstart 事件说明及 IME 部分

并非所有 输入法 (IME) 系统或设备都会向 DOM 提供所需数据,因此活动的组合字符串(“候选窗口”或“候选菜单选项”)可能无法通过此接口获得,在这种情况下,选择内容可以用空字符串表示。

3.8.1. CompositionEvent 接口

本规范中引入

CompositionEvent 接口提供了与组合事件相关的具体上下文信息。

要创建 CompositionEvent 接口实例,请使用 CompositionEvent 构造函数,并传递可选的 CompositionEventInit 字典参数。

3.8.1.1. CompositionEvent
[Exposed=Window]
interface CompositionEvent : UIEvent {
  constructor(DOMString type, optional CompositionEventInit eventInitDict = {});
  readonly attribute USVString data;
};
data, 类型为 USVString,只读
data 保存由输入法生成的字符值。它可以是一个 Unicode 字符,也可以是一个非空的 Unicode 字符序列 [Unicode]。字符应按照 Unicode 规范中的 NFC 归一化形式进行归一化,定义见 [UAX15]。此属性可以为空字符串

此属性的未初始化值必须为 ""(空字符串)。

3.8.1.2. CompositionEventInit
dictionary CompositionEventInit : UIEventInit {
  DOMString data = "";
};
data, 类型为 DOMString,默认值为 ""
初始化 CompositionEvent 对象的 data 属性为 IME 组合生成的字符。

3.8.2. 组合事件顺序

本规范定义的组合事件必须按以下固定顺序发生:

事件类型 备注
1 compositionstart
2 compositionupdate 多次事件
3 compositionend

3.8.3. 手写识别系统

以下示例描述了使用手写识别系统(如在笔平板上)组合文本片段“text”时的可能事件顺序,采用组合事件进行建模:

事件类型 CompositionEvent
data
备注
1 compositionstart ""
用户在平板表面书写单词
2 compositionupdate "test"
用户拒绝第一个单词建议,选择不同的匹配词
3 compositionupdate "text"
4 compositionend "text"

3.8.4. 取消组合事件

如果 keydown 事件被取消,则因该 keydown 事件而产生的任何组合事件不应被分发:

事件类型 备注
1 keydown 已阻止默认行为,如调用 preventDefault()
不会分发组合事件
2 keyup

如果初始 compositionstart 事件被取消,则文本组合会话应被终止。无论组合会话是否终止,compositionend 事件都必须发送。

事件类型 备注
1 keydown
2 compositionstart 已阻止默认行为,如调用 preventDefault()
不会分发组合事件
3 compositionend
4 keyup

3.8.5. 组合期间的按键事件

在组合会话期间,keydownkeyup 事件仍必须被发送,并且这些事件的 isComposing 属性必须为 true

事件类型 KeyboardEvent
isComposing
备注
1 keydown false 这是启动组合的按键事件。
2 compositionstart
3 compositionupdate
4 keyup true
... 组合会话期间发送的所有按键事件必须将 isComposing 设为 true
5 keydown true 这是退出组合的按键事件。
6 compositionend
7 keyup false

3.8.6. 组合期间的输入事件

在组合会话期间,compositionupdate 必须在 beforeinput 发送之后,但在 input 事件发送之前分发。

事件类型 备注
1 beforeinput
2 compositionupdate
此时会进行任何 DOM 更新。
3 input

大多数输入法不支持在组合会话期间取消更新。

beforeinputinput 事件会与 compositionupdate 事件一同发送,只要组合相关 DOM 被更新。由于 compositionend 事件不会导致 DOM 更新,因此此时不应发送 beforeinputinput 事件。

事件类型 备注
1 beforeinput 取消此事件将阻止 DOM 更新和 input 事件。
2 compositionupdate
此时会进行任何 DOM 更新。
3 input 仅当 DOM 被更新时发送。
4 compositionend

3.8.7. 组合事件类型

3.8.7.1. compositionstart
类型 compositionstart
接口 CompositionEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为 启用文本输入法系统时,开始新组合会话
上下文
(可信事件)

用户代理必须在启用文本输入法系统并准备开始(或已经开始,取决于文本输入法系统)新组合会话时分发此事件。该事件类型依赖设备,可能依赖文本转换系统的能力及其在操作系统中的映射。当键盘用于输入法编辑器时,此事件类型在 keydown 事件后生成,但语音或手写识别系统可以在没有键盘事件的情况下发送该事件类型。部分实现可能会用文档当前选中的文本填充 data 属性(用于编辑和替换),否则 data 属性值必须为空字符串

该事件必须在文本输入法系统开始新组合会话,并且在因组合过程修改 DOM 之前立即分发。该事件的默认行为是文本输入法系统开始新组合会话。如果该事件被取消,文本输入法系统应丢弃当前组合会话。

取消 compositionstart 事件类型不同于取消文本输入法系统本身(如点击取消按钮或关闭输入法窗口)。

部分输入法不支持取消正在进行的组合会话(如 GTK 目前没有此类 API)。在这些情况下,调用 preventDefault() 不会阻止该事件的默认行为。

3.8.7.2. compositionupdate
类型 compositionupdate
接口 CompositionEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理应在组合会话期间,当文本输入法系统用新字符更新活动文本片段(即 data 字符串发生变化)时分发此事件。

在需要将组合过程与输入控件保持同步的文本输入法系统中,compositionupdate 事件必须在控件更新之前分发。

部分文本输入法系统可能不会向 DOM 公开此信息,组合过程中不会触发该事件。

如果组合会话被取消,则该事件会在 compositionend 事件之前立即触发,并且 data 属性值将为空字符串

3.8.7.3. compositionend
类型 compositionend
接口 CompositionEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理必须在文本输入法系统完成或取消当前组合会话时分发此事件,并且 compositionend 事件必须在控件更新后分发。

该事件在文本输入法系统完成组合会话(如输入法关闭、最小化、失焦或被切换,焦点切回用户代理时)后立即分发。

4. 键盘事件与按键值

本章节包含有关键盘事件的必要信息:

本章节使用了塞尔维亚语和日文汉字字符,在规范的 PDF 版本或打印版本中可能显示异常或不可用。

4.1. 键盘输入

本节为非规范性内容

每个按键与整个键盘的关系有三个独立方面,每个方面会因不同型号和配置的键盘而有所不同,尤其是因地区特定原因:

本规范仅定义功能映射,即 key 值和 code 值,但会简要介绍 按键标识 作为背景知识。

4.1.1. 按键标识

本节为说明性内容

按键标识是印刷或压印在 按键帽(覆盖按键机械开关的矩形“帽”)上的视觉标记。这些标识通常由一个或多个字符组成,表示按下该键将输入的内容(如 "G""8""ш"),也可以是表示按键功能的名称或符号(如上箭头 "⇧" 代表 Shift,或字符串 "Enter")。人们常用这些标识称呼按键(例如:请按下 "Shift""G" 键。)。但需要注意的是,按键的外观与其数字表示无关,在很多配置下可能完全不准确。即使是控制键和功能键,如 Enter,也可能被映射到不同的功能,甚至被映射为字符键。

许多键盘包含一些通常不会输入字符的按键,即使这些符号在 Unicode 中有对应。例如 Shift 键可能印有符号 "⇧",其 Unicode 编码点为 U+21E7,但按下 Shift 键不会输入该字符值,也不存在 Shift 的 Unicode 编码点。

4.2. 按键代码

按键 code 是键盘事件的一个属性,可用于识别与键盘事件相关联的物理按键。它类似于 USB Usage ID,提供了一个底层值(类似扫描码),并且与厂商无关。

code 属性的主要目的是以一致且连贯的方式根据物理位置识别按键。此外,它还提供了唯一且稳定的名称(不受当前键盘状态影响),可唯一标识键盘上的每个按键。

合法的 code 值列表定义在 [UIEvents-Code] 中。

4.2.1. code 属性的设计动机

标准 PC 键盘有一组按键(称为书写系统按键),它们根据用户当前选择的键盘布局会产生不同的 key 值。这导致无法简单地根据物理位置检测按键,因为代码需要知道当前布局才能判断要检查哪些 key 值。现实场景如某个游戏希望用 "W""A""S""D" 键控制玩家移动。code 属性通过提供一个稳定且不受当前键盘布局影响的值解决了这个问题。

此外,key 属性的值也取决于当前键盘状态。因此,修饰键的按下与释放顺序会影响 key 属性的值。code 属性通过提供一个不受当前键盘状态影响的稳定值解决了这个问题。

4.2.2. keycode 的关系

key
key 属性适用于关注按键实际意义(考虑当前键盘布局和输入法,死键有独特 key 值)的人群。典型用例:检测修饰键或裸修饰键(如响应快捷键)。
code
code 属性适用于关注用户实际按下哪个物理按键的人群,不受布局影响。典型用例:检测 WASD 键(如游戏的移动控制)或拦截所有按键(如远程桌面客户端将所有按键发送到远程主机)。

4.2.3. code 示例

处理左右 Alt 键
键盘布局 KeyboardEvent
key
KeyboardEvent
code
备注
美式 "Alt" "AltLeft" DOM_KEY_LOCATION_LEFT
法式 "Alt" "AltLeft" DOM_KEY_LOCATION_LEFT
美式 "Alt" "AltRight" DOM_KEY_LOCATION_RIGHT
法式 "AltGraph" "AltRight" DOM_KEY_LOCATION_RIGHT

在此示例中,检查 key 属性可以匹配 Alt,无需关心按下的是左 Alt 还是右 Alt 键。检查 code 属性可以匹配右 Alt 键("AltRight"),无需关心当前布局。

注意,在法式键盘示例中,AltAltGraph 键仍然保留左/右位置,即使每种只各有一个键。

处理单引号键
键盘布局 KeyboardEvent
key
KeyboardEvent
code
备注
美式 "'" "Quote"
日文 ":" "Quote"
美式国际 "Dead" "Quote"

此示例展示了死键值如何在属性中编码。key 的值会因当前地区而变化,而 code 属性则始终返回一致值。

处理 "2" 键(按下和未按下 Shift)在不同键盘布局上的情况。
键盘布局 KeyboardEvent
key
KeyboardEvent
code
备注
美式 "2" "Digit2"
美式 "@" "Digit2" shiftKey
英式 "2" "Digit2"
英式 """ "Digit2" shiftKey
法式 "é" "Digit2"
法式 "2" "Digit2" shiftKey

无论当前地区还是修饰键状态如何,在美式键盘上按下标记为 "2" 的按键,code 属性始终为 "Digit2"

键盘事件序列:Shift2

对比下述两个按键事件序列的属性值。它们在美式键盘上都能输入 "@" 字符,但释放按键的顺序不同。第一个序列为:Shift(按下)、2(按下)、2(释放)、Shift(释放)。

事件类型 KeyboardEvent
key
KeyboardEvent
code
备注
1 keydown "Shift" "ShiftLeft" DOM_KEY_LOCATION_LEFT
2 keydown "@" "Digit2" shiftKey
3 keypress "@" "Digit2" (如支持)
4 keyup "@" "Digit2" shiftKey
5 keyup "Shift" "ShiftLeft" DOM_KEY_LOCATION_LEFT

第二个序列中,Shift 在 2 之前释放,事件顺序为:Shift(按下)、2(按下)、Shift(释放)、2(释放)。

事件类型 KeyboardEvent
key
KeyboardEvent
code
备注
1 keydown "Shift" "ShiftLeft" DOM_KEY_LOCATION_LEFT
2 keydown "@" "Digit2" shiftKey
3 keypress "@" "Digit2" (如支持)
4 keyup "Shift" "ShiftLeft" DOM_KEY_LOCATION_LEFT
5 keyup "2" "Digit2"

请注意,key 属性在 "2" 键的 keydown 和 keyup 事件之间值不同。而 code 属性则始终提供一个不受当前修饰键状态影响的稳定值。

4.2.4. code 与虚拟键盘

code 属性对于虚拟键盘(以及遥控器和和弦键盘)的用处并不明显。通常,如果虚拟(或遥控)键盘模仿标准键盘的布局和功能,则也必须适当设置 code 属性。对于不模仿标准键盘布局的键盘,code 属性可以设置为标准键盘上最接近的键,也可以不设置(留空)。

对于虚拟键盘中根据修饰键状态产生不同值的按键,code 值应为设备处于出厂重置状态时按下该按钮时生成的 key 值。

4.3. 键盘事件 key

按键值是一个 DOMString,用于表示键盘上的任意按键(无论位置或状态),以其所产生的值区分。这些按键值可以作为实现生成的键盘事件的返回值,也可以由内容作者用作输入(如用于键盘快捷键)。

合法的 key 值列表定义在 [UIEvents-Key] 中。

内容作者可以通过 key 属性检测按键被按下时的值,可以获得大写或小写字母、数字、符号或其他能产生字符的按键的字符值,也可以获得控制键、修饰键、功能键或其他不产生字符的按键的按键值。这些值可用于监控特定输入字符串、检测并响应修饰键与其他输入(如鼠标)组合、创建虚拟键盘或其他用途。

按键值也可以用于字符串比较、作为标签属性值(如 HTML accesskey),或其它相关用途。符合规范的宿主语言应允许内容作者使用按键值的两个等价字符串之一:字符值按键值

虽然实现会根据平台或键盘布局独立使用最相关的按键值,但内容作者不能假设键盘设备都能生成这些值。在用作快捷键组合时,可以考虑使用数字和功能键(F4F5等)而不是字母[DWW95]),因为大多数键盘布局都提供这些键。

按键值不表示物理键盘上的具体按键,也不反映按键上印刷的字符。按键值表示事件的当前值,会考虑所有活动按键和输入模式(包括 shift 模式)的当前状态,由操作系统的键盘映射反映并报告给实现。换言之,QWERTY 键盘上标记为 O 的键在未按 shift 时 "o",按下 shift 时为 "O"。由于用户可将键盘映射为任意自定义配置,内容作者不应假设按键的 shift/unshift 状态与字符的大小写存在对应关系,而应始终使用 key 属性值。例如,[UIEvents-Code] 中的 Standard "102" 键盘布局展示了一种可能的按键映射,还有许多其它标准或个性化布局。

为简化死键支持,当操作系统键盘映射处于死键状态时,死键序列的当前状态不会通过 key 属性报告,而会报告按键值 "Dead"。实现会生成组合事件,其中死键序列的中间状态通过 data 属性报告。如前例,QWERTY 键盘上的 O 键在添加变音符时,未按 shift 时 "ö",按下 shift 时 "Ö"

还要注意,按键事件状态与按键值之间不是一一对应关系。某个按键值可能关联多个按键。例如,许多标准键盘有多个 Shift 键值(通常通过 locationDOM_KEY_LOCATION_LEFTDOM_KEY_LOCATION_RIGHT 区分),或多个 8 键值(通过 locationDOM_KEY_LOCATION_STANDARDDOM_KEY_LOCATION_NUMPAD 区分),用户自定义布局可在多个按键状态下重复任何按键值(注意 location 主要用于标准键盘布局,不能总能区分)。

最后,任意字符表示的意义取决于具体上下文且较为复杂。例如,在某些上下文下,星号符号("*")表示脚注或强调(如包围文本段落),但在某些文档或程序中等价于乘法运算符,而在其他文档或程序中该功能由乘号符号("×",Unicode 编码 U+00D7)或小写字母 "x" 实现(因多数键盘无专用乘号键且符号形似)。因此字符表示的语义和功能不属于本规范范围。

4.3.1. 修饰键

键盘输入使用修饰键改变按键的正常行为。和其它按键一样,修饰键会生成 keydownkeyup 事件(如下例)。部分修饰键在按下或持续按下时激活,如 AltControlShiftAltGraphMeta。其他修饰键根据其状态激活,如 CapsLockNumLockScrollLock。状态变化发生在按下修饰键时。KeyboardEvent 接口为部分常见修饰键提供了便捷属性:ctrlKeyshiftKeyaltKeymetaKey。部分操作系统用 Alt + Control 组合模拟 AltGraph 修饰键。建议实现优先采用 AltGraph 修饰键。

此示例展示美式键盘(US mapping)上输入 Unicode 字符 Q(拉丁大写字母 Q,Unicode 编码 U+0051)时可能的事件序列:
事件类型 KeyboardEvent
key
修饰键 备注
1 keydown "Shift" shiftKey
2 keydown "Q" shiftKey 拉丁大写字母 Q
3 beforeinput
4 input
5 keyup "Q" shiftKey
6 keyup "Shift"
本示例展示与上述不同的按键顺序:先释放 Shift 键,再释放 Q 键。此时 Q 键在 keyup 事件中的值会变为未修饰状态:
事件类型 KeyboardEvent
key
修饰键 备注
1 keydown "Shift" shiftKey
2 keydown "Q" shiftKey 拉丁大写字母 Q
3 beforeinput
4 input
5 keyup "Shift"
6 keyup "q" 拉丁小写字母 Q
下例描述一组不会生成 Unicode 字符的按键序列(配置同前例):
事件类型 KeyboardEvent
key
修饰键 备注
1 keydown "Control" ctrlKey
2 keydown "v" ctrlKey 拉丁小写字母 V
不生成 beforeinputinput 事件。
3 keyup "v" ctrlKey 拉丁小写字母 V
4 keyup "Control"
下例展示同时按下 ShiftControl 时的事件序列:
事件类型 KeyboardEvent
key
修饰键 备注
1 keydown "Control" ctrlKey
2 keydown "Shift" ctrlKey, shiftKey
3 keydown "V" ctrlKey, shiftKey 拉丁大写字母 V
不生成 beforeinputinput 事件。
4 keyup "V" ctrlKey, shiftKey 拉丁大写字母 V
5 keyup "Shift" ctrlKey
6 keyup "Control"
对于非美式键盘布局,事件顺序相同,但按键值取决于当前键盘布局。下例展示在阿拉伯语键盘布局下的事件序列:
事件类型 KeyboardEvent
key
修饰键 备注
1 keydown "Control" ctrlKey
2 keydown "ر" ctrlKey 阿拉伯字母 Reh
不生成 beforeinputinput 事件。
3 keyup "ر" ctrlKey 阿拉伯字母 Reh
4 keyup "Control"

keydownkeyup 事件中的值会根据按下按键时所用的键盘布局而变化。这意味着美式布局下的 v 键和阿拉伯语布局下的 ر 键虽然是同一个物理按键,但会生成不同的事件。要识别这些事件来自同一物理按键,应使用 code 属性。

在某些情况下,修饰键会改变按键事件的 key 值。例如,在部分 MacOS 键盘上,标记为 "delete" 的键在未修饰时与 Windows 上的 Backspace 功能相同,但与 Fn 键组合时则变为 Delete 键,此时 key 的值会匹配当前修饰状态下最合适的功能。

4.3.2. 死键

有些键盘输入会使用死键来输入组合字符序列。与手写输入不同,手写输入用户先输入基础字符,而键盘输入则需要在按下死键时进入特殊状态,只有在输入有限的几个“合法”基础字符后才会发出字符。

MacOS 和 Linux 操作系统通过输入法处理死键

所有键盘布局和映射中的死键都以按键值 Dead 表示。每次死键按下时,用户代理必须分发 组合事件,并且 compositionupdate 事件的 data 值必须为当前死键组合序列的字符值。

Unicode 组合字符总是遵循手写输入顺序,即组合字符跟在对应字母之后,而典型的死键输入可能会反转顺序,即组合字符在字母之前。例如,单词 naïve 使用组合变音符 ¨ 时,Unicode 顺序是 nai¨ve,但实际输入时可能为 na¨ive。键入 U+0302(组合抑扬符死键)和 U+0065(标记为拉丁小写字母 e 的键)在法语键盘且未激活任何修饰键时,通常会产生 Unicode 字符 "ê"(拉丁小写字母 e 带抑扬符),符合 Unicode 归一化形式 NFC 的首选。

事件类型 KeyboardEvent
key
KeyboardEvent
isComposing
CompositionEvent
data
备注
1 keydown "Dead" false 组合抑扬符(死键)
2 compositionstart ""
3 compositionupdate U+0302
4 keyup "Dead" true
5 keydown "ê" true
6 compositionupdate "ê"
7 compositionend "ê"
8 keyup "e" false 拉丁小写字母 e

在第二个 keydown 事件(第5步),按键值(假定事件未被屏蔽)不会"e"(拉丁小写字母 e),因为用户代理接收到的值已被死键操作修改。

当用户在按下死键后输入了不支持的基础字符(即该基础字符没有激活的变音符可用),该过程可能会被中断:

事件类型 KeyboardEvent
key
KeyboardEvent
isComposing
CompositionEvent
data
备注
1 keydown "Dead" false 组合抑扬符(死键)
2 compositionstart ""
3 compositionupdate U+0302
4 keyup "Dead" true
5 keydown "q" true 拉丁小写字母 q
6 compositionupdate ""
7 compositionend ""
8 keyup "q" false

4.3.3. 输入法编辑器

本规范通过 CompositionEvent 接口和相应事件,包含了输入法编辑器(IME)的模型。 然而,组合事件与键盘事件并不总是存在一一对应关系。例如,收到 keydown 事件且按键值为 Accept 时,并不一定意味着当前在输入法中选中的文本被“接受”,只表示有一次按键发生,与 输入法的“接受”功能无关(通常在多数输入法系统中会触发 compositionend 事件)。键盘事件无法用于判断输入法编辑器的当前状态,应通过 data 属性在 CompositionEvent 接口获取。此外,不同的输入法系统和设备功能不同,激活这些功能的按键也不同,ConvertAccept 键也可能由其他可用按键表示。键盘事件对应于键盘布局映射之后由输入设备生成的事件。

在部分实现或系统配置下,部分按键事件及其值可能会被正在使用的输入法抑制。

下例展示了通过日语输入法生成 Unicode 字符 "市"(汉字,CJK统一表意文字之一)的一组可能按键序列。假定输入法已激活并处于日文罗马字输入模式。ConvertAccept 键可能被其他按键替换,具体取决于输入设备和输入法配置,例如分别可以是 U+0020(空格键)和 Enter

"詩"(诗)和 "市"(市)为同音字,都读作 し(shi/si),用户需用 Convert 键选择正确选项。

事件类型 KeyboardEvent
key
KeyboardEvent
isComposing
CompositionEvent
data
备注
1 keydown "s" false 拉丁小写字母 S
2 compositionstart ""
3 beforeinput
4 compositionupdate "s"
DOM 已更新
5 input
6 keyup "s" true
7 keydown "i" true 拉丁小写字母 I
8 beforeinput
9 compositionupdate "し" shi
DOM 已更新
10 input
11 keyup "i" true
12 keydown "Convert" true 转换
13 beforeinput
14 compositionupdate "詩" "诗"
DOM 已更新
15 input
16 keyup "Convert" true
17 keydown "Convert" true 转换
18 beforeinput
19 compositionupdate "市" "市"
DOM 已更新
20 input
21 keyup "Convert" true
22 keydown "Accept" true 接受
23 compositionend "市"
24 keyup "Accept" false

IME 组合也可以被取消,条件与上述示例相同。Cancel 键也可能由其他按键替换,具体取决于输入设备和输入法配置,例如可以是 U+001B(Esc键)。

事件类型 KeyboardEvent
key
KeyboardEvent
isComposing
CompositionEvent
data
备注
1 keydown "s" false 拉丁小写字母 S
2 compositionstart ""
3 compositionupdate "s"
4 keyup "s" true
5 keydown "i" true 拉丁小写字母 I
6 compositionupdate "し" shi
7 keyup "i" true
8 keydown "Convert" true 转换
9 compositionupdate "詩" "诗"
10 keyup "Convert" true
11 keydown "Convert" true 转换
12 compositionupdate "市" "市"
13 keyup "Convert" true
14 keydown "Cancel" true 取消
15 compositionupdate ""
16 compositionend ""
17 keyup "Cancel" false

部分输入法编辑器(如 MacOS 操作系统上的输入法)可能会在取消组合前将组合数据属性设为空字符串

4.3.3.1. 输入法编辑器模式按键

某些设备上的部分按键用于激活输入法编辑器功能,或用于更改活动输入法编辑器的模式。不同设备或语言模式可以自定义这些按键。本规范定义了如下用于该目的的按键:"Alphanumeric""CodeInput""FinalMode""HangulMode""HanjaMode""Hiragana""JunjaMode""KanaMode""KanjiMode""Katakana""Romaji"。当按下这些按键之一且当前没有输入法激活时,预期会以该按键指示的模式激活相应输入法(如可用)。如果按键按下时已有输入法激活,则当前输入法可能切换到指定模式,也可能启动不同的输入法,或者该按键可能被忽略,具体取决于设备和应用。

本规范还定义了其它专门用于输入法编辑器的按键:"Accept""AllCandidates""Cancel""Convert""Compose""Zenkaku" (全角)、"Hankaku" (半角)、"NextCandidate""NonConvert", 以及 "PreviousCandidate"。这些按键的具体功能未在本规范定义——详情参见其它输入法相关资源。

具有输入法编辑器功能的按键不仅限于此用途,也可以有其他设备或实现特定的用途。

4.3.4. 默认行为与可取消的键盘事件

取消默认行为keydown事件不会影响其对应的keyup事件,但必须阻止对应的beforeinputinput(如果支持还包括keypress)事件的生成。下例展示美式键盘(US mapping)输入 Unicode 字符 Q(拉丁大写字母 Q)时的按键序列:

事件类型 KeyboardEvent
key
InputEvent
data
修饰键 备注
1 keydown "Shift" shiftKey
2 keydown "Q" shiftKey 已阻止默认行为,如调用 preventDefault()
不会生成 beforeinputinput (或 keypress,如支持)事件
3 keyup "Q" shiftKey
4 keyup "Shift"

如果按键为修饰键,则按键操作必须仍然影响修饰键状态。下例展示美式键盘输入 Unicode 字符 Q(拉丁大写字母 Q)时可能的按键序列:

事件类型 KeyboardEvent
key
InputEvent
data
修饰键 备注
1 keydown "Shift" shiftKey 已阻止默认行为,如调用 preventDefault()
2 keydown "Q" shiftKey
3 beforeinput "Q"
4 input
5 keyup "Q" shiftKey
6 keyup "Shift"

如果按键属于一组多个按键序列(无论是死键还是输入法编辑器序列),只有在keydown事件上取消了默认行为,该按键才能被忽略(不计入序列)。在keyup事件上取消死键不会影响beforeinputinput事件。下例在法语键盘(French mapping)未激活修饰键时,使用死键 "Dead"U+0302 组合抑扬符死键)和 "e"U+0065,拉丁小写字母 e 键):

事件类型 KeyboardEvent
key
InputEvent
data
备注
1 keydown "Dead" 已阻止默认行为,如调用 preventDefault()
2 keyup "Dead"
3 keydown "e"
4 beforeinput "e"
5 input
6 keyup "e"

5. 外部算法

本节包含本规范所需,但更应由其他规范托管的算法。

本节旨在作为这些定义的临时归属地,最终应将其迁移到更合适的规范中,届时可删除本节。

5.1. 核心 DOM 算法

下述算法应迁移到其他地方……

5.1.1. 命中测试

输入

pos,相对于视口的 x,y 坐标

输出

pos 位置最前面的 DOM 元素

为适配 inertdisabled 元素,应调用 elementsFromPoint 并排除无效元素

  1. 返回 [CSSOM-View]elementFromPoint,参数为 pos

5.1.2. 计算 DOM 路径

输入

element,起始元素

输出

给定元素的祖先元素列表

  1. path = 一个包含 element 的列表

    该定义需完善如何将祖先添加到 path

  2. 返回 path

5.2. PointerLock 算法

下述算法应迁移到 [PointerLock] 规范。

5.2.1. PointerLock 全局状态

5.2.1.1. 窗口级状态

UA 必须维护如下窗口级共享值。

一个 last mouse move 值(初始为未定义),记录最近一次 mousemove 事件的位置。

5.2.2. 初始化 MouseEvent 的 PointerLock 属性

输入

event,一个 MouseEvent

输出

  1. 设置 event.movementX = 0

  2. 设置 event.movementY = 0

5.2.3. 设置 mousemove 的 PointerLock 属性

输入

event,一个 MouseEvent

输出

  1. 如果 event.type 不是 "mousemove",则退出

  2. 如果 last mouse move 未定义,则

    1. 设置 event.movementX = 0

    2. 设置 event.movementY = 0

  3. 否则,

    1. 设置 event.movementX = event.screenX - last mouse move 的 x 坐标

    2. 设置 event.movementY = event.screenX - last mouse move 的 y 坐标

  4. 设置 last mouse move = ( event.screenX, event.screenY )

5.3. PointerEvent 算法

下述算法应迁移到 [PointerEvents3] 规范。

5.3.1. 初始化 PointerEvent

输入

event,要初始化的 PointerEvent

eventType,包含事件类型的 DOMString

eventTarget,事件的 EventTarget

输出

  1. eventeventTypeeventTarget 初始化 MouseEvent

TODO - 初始化 pointerevent 属性

5.3.2. 创建 PointerEvent

输入

eventType,包含事件类型的 DOMString

eventTarget,事件的 EventTarget

输出

  1. event = 创建新事件,类型为 PointerEvent

  2. eventeventTypeeventTarget 初始化 PointerEvent

  3. 返回 event

5.3.3. 由 MouseEvent 创建 PointerEvent

输入

eventType,包含事件类型的 DOMString

mouseevent,对应的 MouseEvent

输出

  1. event = 创建新事件,类型为 PointerEvent

  2. target = mouseevent.target

  3. eventeventTypetarget 初始化 PointerEvent

  4. 将 MouseEvent 属性从 mouseevent 复制到 event

  5. 返回 event

5.3.4. 可能发送 pointerout 事件

输入

mouseout,对应的 mouseout MouseEvent

输出

  1. pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent

  2. 设置 pointerevent 属性

    TODO

  3. target = mouseout.target

  4. 派发 pointerouttarget

5.3.5. 可能发送 pointerleave 事件

输入

mouseout,对应的 mouseout MouseEvent

输出

  1. pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent

  2. 设置 pointerevent 属性

    TODO

  3. target = mouseout.target

  4. 派发 pointerouttarget

5.3.6. 可能发送 pointerover 事件

输入

mouseout,对应的 mouseout MouseEvent

输出

  1. pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent

  2. 设置 pointerevent 属性

    TODO

  3. target = mouseout.target

  4. 派发 pointerouttarget

5.3.7. 可能发送 pointerenter 事件

输入

mouseout,对应的 mouseout MouseEvent

输出

  1. pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent

  2. 设置 pointerevent 属性

    TODO

  3. target = mouseout.target

  4. 派发 pointerouttarget

5.3.8. 可能发送 pointermove 事件

输入

mouseout,对应的 mouseout MouseEvent

输出

这个方法可以同时发送 pointermove 和 pointerrawupdate 吗?还是需要两个方法?

如何合理定义 pointermove 事件的合并行为?

  1. pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent

  2. 设置 pointerevent 属性

    TODO

  3. target = mouseout.target

  4. 派发 pointerouttarget

5.3.9. 可能发送 pointerdown 事件

输入

mouseout,对应的 mouseout MouseEvent

输出

与 mousedown 事件不同,当多个按钮被同时按下时,pointerdown 事件不会嵌套。 传递 MouseEvent 以便字段可以复制到 PointerEvent 中。

  1. pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent

  2. 设置 pointerevent 属性

    TODO

  3. target = mouseout.target

  4. 派发 pointerouttarget

5.3.10. 可能发送 pointerup 事件

输入

mouseout,对应的 mouseout MouseEvent

输出

与 mouseup 事件不同,当多个按钮被同时按下时,pointerup 事件不会嵌套。 传递 MouseEvent 以便字段可以复制到 PointerEvent 中。

  1. pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent

  2. 设置 pointerevent 属性

    TODO

  3. target = mouseout.target

  4. 派发 pointerouttarget

6. 遗留事件初始化器

本节为规范性内容。 下列特性已废弃,仅应由用户代理实现,以兼容旧版软件。

本规范早期版本在接口上包含初始化方法(如 initMouseEvent),需要大量参数,但在大多数情况下,无法完全初始化事件对象的所有属性。因此,继承自基础 Event 接口的事件接口,要求每个派生接口的初始化器都要显式调用,才能完全初始化一个事件。

初始化 UIEvent 的所有属性需要调用两个初始化方法:initEventinitUIEvent

由于该标准开发周期较长,部分实现可能依赖这些(现已废弃的)初始化方法。为完整性考虑,本文附录描述了这些遗留事件初始化器。

6.1. 遗留事件初始化器接口

本节为说明性内容

本节记录了本规范早期版本引入的遗留初始化方法。

6.1.1. UIEvent 接口初始化器

partial interface UIEvent {
  // 本规范已废弃
  undefined initUIEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional Window? viewArg = null,
    optional long detailArg = 0);
};
initUIEvent(typeArg)
初始化 UIEvent 对象的属性。 此方法行为与 initEvent() 相同。

initUIEvent 方法已废弃,但为兼容大量已部署实现仍支持。

DOMString typeArg
参见 initEvent() 方法参数说明。
boolean bubblesArg
参见 initEvent() 方法参数说明。
boolean cancelableArg
参见 initEvent() 方法参数说明。
Window? viewArg
指定 view。该值可为 null
long detailArg
指定 detail

6.1.2. MouseEvent 接口初始化器

partial interface MouseEvent {
  // 本规范已废弃
  undefined initMouseEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional Window? viewArg = null,
    optional long detailArg = 0,
    optional long screenXArg = 0,
    optional long screenYArg = 0,
    optional long clientXArg = 0,
    optional long clientYArg = 0,
    optional boolean ctrlKeyArg = false,
    optional boolean altKeyArg = false,
    optional boolean shiftKeyArg = false,
    optional boolean metaKeyArg = false,
    optional short buttonArg = 0,
    optional EventTarget? relatedTargetArg = null);
};
initMouseEvent(typeArg)
初始化 MouseEvent 对象的属性。该方法行为与 UIEvent.initUIEvent() 相同。

initMouseEvent 方法已废弃,但为兼容大量已部署实现仍支持。

DOMString typeArg
参见 initEvent() 方法参数说明。
boolean bubblesArg
参见 initEvent() 方法参数说明。
boolean cancelableArg
参见 initEvent() 方法参数说明。
Window? viewArg
指定 view。该值可以为 null
long detailArg
指定 detail
long screenXArg
指定 screenX
long screenYArg
指定 screenY
long clientXArg
指定 clientX
long clientYArg
指定 clientY
boolean ctrlKeyArg
指定 ctrlKey
boolean altKeyArg
指定 altKey
boolean shiftKeyArg
指定 shiftKey
boolean metaKeyArg
指定 metaKey
short buttonArg
指定 button
EventTarget? relatedTargetArg
指定 relatedTarget。该值可以为 null

6.1.3. KeyboardEvent 接口初始化器

该遗留 KeyboardEvent 初始化器的参数列表不包含 detailArg(其它初始化器有),并新增了 locale 参数;为兼容现有实现必须保留此不一致性。

partial interface KeyboardEvent {
  // 本规范最初引入(现已废弃)
  undefined initKeyboardEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional Window? viewArg = null,
    optional DOMString keyArg = "",
    optional unsigned long locationArg = 0,
    optional boolean ctrlKey = false,
    optional boolean altKey = false,
    optional boolean shiftKey = false,
    optional boolean metaKey = false);
};
initKeyboardEvent(typeArg)
初始化 KeyboardEvent 对象的属性。该方法行为与 UIEvent.initUIEvent() 相同。 detail 的值保持未定义。

initKeyboardEvent 方法已废弃。

DOMString typeArg
参见 initEvent() 方法参数说明。
boolean bubblesArg
参见 initEvent() 方法参数说明。
boolean cancelableArg
参见 initEvent() 方法参数说明。
Window? viewArg
指定 view。该值可以为 null
DOMString keyArg
指定 key
unsigned long locationArg
指定 location
boolean ctrlKey
指定 Control 键修饰符是否激活。
boolean altKey
指定 Alt 键修饰符是否激活。
boolean shiftKey
指定 Shift 键修饰符是否激活。
boolean metaKey
指定 Meta 键修饰符是否激活。

6.1.4. CompositionEvent 接口初始化器

该遗留 CompositionEvent 初始化器的参数列表不包含 detailArg(其它初始化器有),并新增了 locale 参数;为兼容现有实现必须保留此不一致性。

partial interface CompositionEvent {
  // 本规范最初引入(现已废弃)
  undefined initCompositionEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional WindowProxy? viewArg = null,
    optional DOMString dataArg = "");
};
initCompositionEvent(typeArg)
初始化一个 CompositionEvent 对象的属性。该方法的行为与 UIEvent.initUIEvent() 相同。detail 的值保持未定义。

initCompositionEvent 方法已废弃。

DOMString typeArg
参见 initEvent() 方法参数说明。
boolean bubblesArg
参见 initEvent() 方法参数说明。
boolean cancelableArg
参见 initEvent() 方法参数说明。
Window? viewArg
指定 view。该值可以为 null
DOMString dataArg
指定 data

7. 传统键盘和鼠标事件属性

本节为非规范性内容。以下属性已废弃,仅应由需要与传统软件兼容的用户代理实现,这些软件需要这些键盘事件。

这些特性从未被正式规范,目前各浏览器的实现存在显著差异。大量传统内容(包括脚本库)依赖于检测用户代理并据此操作,这意味着任何对这些传统属性和事件的正式规范化尝试都可能带来与修复同样多的问题。此外,这些属性不适用于国际化,也未解决可访问性问题。

因此,本规范未对常用于处理键盘输入的事件和属性进行规范性定义,尽管它们可能会在用户代理中出现以兼容传统内容。作者应使用key 属性,而不是charCodekeyCode 属性。

不过,为了说明这些特性当前的状态及其与规范性事件和属性的关系,本节提供了相关的说明性描述。对于支持这些属性和事件的实现,建议参考本节提供的定义。

7.1. 传统 UIEvent 补充接口

本节为非规范性内容

用户代理通常包含一个which 属性,以便KeyboardEventMouseEvent 可以记录补充事件信息。

以往版本的规范曾在KeyboardEventMouseEvent 上分别定义which 属性,而不是在UIEvent 上定义共享的which 属性。

7.1.1. 接口 UIEvent(补充)

部分UIEvent 接口是对UIEvent 接口的说明性扩展,增加了which 属性。

partial interface UIEvent {
  // 以下用于支持传统用户代理
  readonly attribute unsigned long which;
};
which, 类型为 unsigned long,只读
对于MouseEvent, 包含的值等于button+1。 对于KeyboardEvent, 保存与按下的键相关的未修改标识符的系统和实现相关的数值代码。多数情况下,此值与keyCode相同。

7.1.2. 接口 UIEventInit(补充)

包含对which 的支持的浏览器应在UIEvent 中添加以下成员到UIEventInit 字典。

部分UIEventInit 字典是对UIEventInit 字典的说明性扩展,增加了which 成员用于初始化对应的UIEvent 属性。

partial dictionary UIEventInit {
  unsigned long which = 0;
};
which, 类型为 unsigned long,默认值为0
初始化which 属性到UIEvent

7.2. 传统 KeyboardEvent 补充接口

本节为非规范性内容

浏览器对键盘的支持传统上依赖于三个临时属性:keyCodecharCode, 以及UIEventwhich

这三个属性均返回表示所按下键的某些方面的数值编码:keyCode 是键自身的索引;charCode 是字符键的 ASCII 值;which 在可用时为字符值,否则为键索引。这些属性的值及是否可用,在不同平台、键盘语言和布局、用户代理、版本甚至事件类型之间均不一致。

7.2.1. 接口 KeyboardEvent(补充)

部分KeyboardEvent 接口是对 KeyboardEvent 接口的说明性扩展,增加了charCodekeyCode 属性。

部分KeyboardEvent 接口可通过在支持该扩展的实现中调用createEvent() 方法获得。

partial interface KeyboardEvent {
  // 以下用于支持传统用户代理
  readonly attribute unsigned long charCode;
  readonly attribute unsigned long keyCode;
};
charCode, 类型为 unsigned long,只读
charCode 保存字符值,对于生成字符输入的keypress事件,其值为该字符的 Unicode 编号(例如对于可打印字符 event.charCode = event.key.charCodeAt(0))。对于keydownkeyup事件,charCode 的值为0
keyCode, 类型为 unsigned long,只读
keyCode 保存与按下的键相关的未修改标识符的系统和实现相关的数值代码。与key 属性不同,可能值的集合未在本规范中规范化。通常, keyCode 的值应代表 ASCII [RFC20][US-ASCII] 或 Windows 1252 [WIN1252] 的十进制编码,但也可以来自其他适当的字符集。无法识别按键时,键值为0

详见§ 7.3 传统键位模型,了解如何确定keyCode 的值。

7.2.2. 接口 KeyboardEventInit(补充)

包含对keyCodecharCode 支持的浏览器应在KeyboardEvent 中添加以下成员到KeyboardEventInit 字典。

部分KeyboardEventInit 字典是对KeyboardEventInit 字典的说明性扩展,增加了charCodekeyCode 成员用于初始化对应的KeyboardEvent 属性。

partial dictionary KeyboardEventInit {
  // 以下用于支持传统用户代理
  unsigned long charCode = 0;
  unsigned long keyCode = 0;
};
charCode, 类型为 unsigned long,默认值为0
初始化charCode 属性到KeyboardEvent 的对应字符的 Unicode 编码。
keyCode, 类型为 unsigned long,默认值为0
初始化keyCode 属性到KeyboardEvent 的系统和实现相关的未修改标识符的数值代码。

7.3. 传统键位模型

本节为非规范性内容

不同实现会为不同事件类型暴露这些属性的不同值。实现可以选择在keyCode 属性中同时暴露虚拟键码和字符码(混合模型),或者分别报告keyCodecharCode 属性(分离模型)。

7.3.1. 如何确定keyCode用于keydownkeyup事件

keyCodekeydownkeyup事件中计算规则如下:

7.3.2. 如何确定keyCode用于keypress 事件

keyCodekeypress事件中计算规则如下:

7.3.3. 固定虚拟键码

以下这些键的虚拟键码在桌面系统的键盘布局中通常不会改变:

虚拟键码 备注
Backspace 8
Tab 9
Enter 13
Shift 16
Control 17
Alt 18
CapsLock 20
Escape 27 Esc
Space 32
PageUp 33
PageDown 34
End 35
Home 36
ArrowLeft 37
ArrowUp 38
ArrowRight 39
ArrowDown 40
Delete 46 Del

7.3.4. 可选固定虚拟键码

以下标点符号在不同键盘布局间虚拟码可能变化,但报告这些值更有可能与期望美国英文键盘布局的传统内容兼容:

字符 虚拟键码
Semicolon ";" 186
Colon ":" 186
Equals sign "=" 187
Plus "+" 187
Comma "," 188
Less than sign "<" 188
Minus "-" 189
Underscore "_" 189
Period "." 190
Greater than sign ">" 190
Forward slash "/" 191
Question mark "?" 191
Backtick "`" 192
Tilde "~" 192
Opening squace bracket "[" 219
Opening curly brace "{" 219
Backslash "\" 220
Pipe "|" 220
Closing square bracket "]" 221
Closing curly brace "}" 221
Single quote "'" 222
Double quote """ 222

8. 传统事件类型

本节为规范性内容。以下事件类型已废弃,仅应由需要与传统软件兼容的用户代理实现。

本节的目的是记录这些特性的当前状态及其与规范性事件的关系。对于支持这些事件的实现,建议采用本节给出的定义。

下表提供了本规范中已弃用事件类型的说明性摘要,供参考和完整性之用。

事件类型 同步 / 异步 冒泡阶段 可信事件目标类型 DOM 接口 可取消 可组合 默认行为
DOMActivate 同步 Element UIEvent
DOMFocusIn 同步 Window, Element FocusEvent
DOMFocusOut 同步 Window, Element FocusEvent
keypress 同步 Element KeyboardEvent 视情况而定:启动文本输入法系统blurfocus事件;DOMActivate事件;其他事件
textInput 同步 Element TextEvent 见定义

8.1. 传统 UIEvent 事件

8.1.1. 传统 UIEvent 事件类型

8.1.1.1. DOMActivate
类型 DOMActivate
接口 UIEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
可组合
默认行为
上下文
(可信事件)

当按钮、链接或其他改变状态的元素被激活时,用户代理必须分发此事件。

DOMActivate事件类型在本规范中出于参考和完整性定义,但本规范弃用了此事件类型,建议改用相关的事件类型click。其他规范可为兼容旧内容定义和维护自己的DOMActivate事件类型

虽然DOMActivateclick并不完全等效,但click事件类型的实现已涵盖了为DOMActivate事件类型设计的最关键可访问性方面,并且应用更广泛。内容作者鼓励使用click事件类型,而不是相关的mousedownmouseup事件类型,以确保最大可访问性。

支持DOMActivate事件类型的实现,也应在与激活触发器关联的click事件的默认行为中分发DOMActivate事件。但此类实现应确保每次激活触发器只启动一次相关的激活行为

DOMActivate事件类型是 XForms [XFORMS11]所需,适用于在宿主语言中实现。在插件或基于脚本的 XForms 实现要安装到本规范的原生实现且不支持DOMActivate事件类型的场景下,XForms用户代理需要根据合适的激活触发器自行合成并分发DOMActivate事件。

因此,当符合 UI Events 的click事件被用户代理分发时,XForms用户代理需要判断是否要根据该click事件的默认行为合成一个具有相同相关属性的DOMActivate事件。判断线索可能包括click事件的isTrusted属性,或其事件目标是否已注册DOMActivate事件监听器

不要依赖于多数DOMActivate在众多用户代理中的互操作支持。应使用click事件类型,因其更广泛的实现支持能带来更好的可访问性。

DOMActivate事件类型在本规范中已被弃用。

8.1.2. 激活事件顺序

如果用户代理支持DOMActivate事件,则事件必须按如下顺序分发(仅列出相关事件):

事件类型 备注
1 click
2 DOMActivate 默认行为,如用户代理支持;合成;isTrusted="true"
3 所有其他默认行为,包括激活行为

如果通过按键事件激活焦点元素,则如下为典型事件顺序(仅列出相关事件):

事件类型 备注
1 keydown 必须是可激活元素的按键,如Enter (空格键),否则元素不会被激活
2 click 默认行为;合成;isTrusted="true"
3 DOMActivate 默认行为,如用户代理支持;合成;isTrusted="true"
4 所有其他默认行为,包括激活行为

8.2. 传统 FocusEvent 事件

8.2.1. 传统 FocusEvent 事件类型

8.2.1.1. DOMFocusIn
类型 DOMFocusIn
接口 FocusEvent
同步 / 异步 同步
冒泡
可信目标 Window, Element
可取消
可组合
默认行为
上下文
(可信事件)

用户代理事件目标获得焦点时,必须分发此事件。必须在分发此事件类型之前将焦点赋予该元素。此事件类型必须在focus事件类型之后分发。

DOMFocusIn事件类型在本规范中仅为参考和完整性定义,但本规范弃用了该事件类型,建议使用相关的focusfocusin事件类型。

8.2.1.2. DOMFocusOut
类型 DOMFocusOut
接口 FocusEvent
同步 / 异步 同步
冒泡
可信目标 Window, Element
可取消
组合事件
默认行为
上下文
(可信事件)

用户代理检测到事件目标失去焦点时,必须派发此事件。在派发该事件类型之前,必须先将焦点从元素移除。该事件类型必须在blur事件类型之后派发。

DOMFocusOut事件类型在本规范中定义仅供参考和完整性考虑,但本规范弃用该事件类型的使用, 推荐使用相关事件类型blurfocusout代替。

8.2.2. 传统 FocusEvent 事件顺序

以下展示了当焦点在元素间切换时的典型事件顺序,包括已弃用的DOMFocusInDOMFocusOut事件。假定初始没有元素获得焦点。

事件类型 备注
用户切换焦点
1 focusin 在第一个目标元素获得焦点前发送
2 focus 在第一个目标元素获得焦点后发送
3 DOMFocusIn 如支持则发送
用户切换焦点
4 focusout 在第一个目标元素失去焦点前发送
5 focusin 在第二个目标元素获得焦点前发送
6 blur 在第一个目标元素失去焦点后发送
7 DOMFocusOut 如支持则发送
8 focus 在第二个目标元素获得焦点后发送
9 DOMFocusIn 如支持则发送

8.3. 传统KeyboardEvent 事件

keypress事件是传统用于捕获按键事件并在 DOM 更新按键效果之前进行处理的方法。使用keypress事件的代码通常依赖于传统属性charCodekeyCode, 和which属性。

注意keypress事件仅用于按键事件,已被更通用的beforeinputinput事件序列所替代。新的input事件不再特定于键盘操作,可用于捕获任意来源的用户输入。

8.3.1. 传统KeyboardEvent 事件类型

8.3.1.1. keypress
类型 keypress
接口 KeyboardEvent
同步 / 异步 同步
冒泡
可信目标 Element
可取消
组合事件
默认行为 不同情况: 启动文本输入系统blurfocus 事件;DOMActivate事件; 其他事件
上下文
(可信事件)

用户代理支持,则当按下一个正常会产生字符值的按键时,必须派发此事件。 keypress事件类型依赖输入设备的能力及其在操作系统中的映射,因此具有设备依赖性。

该事件类型必须在键映射之后生成。使用输入法编辑器时不得触发此事件。

如事件被取消,除取消默认行为外,还应阻止input事件的触发。

作者应优先使用beforeinput事件而非keypress事件。

keypress事件通常用于检测字符值而不是物理按键,因此某些配置下并非所有按键都能触发该事件。

keypress 事件类型在本规范中定义仅供参考和完整性考虑,但本规范弃用该事件类型。在编辑场景中,作者应订阅beforeinput事件。

8.3.2. keypress 事件顺序

keypress事件类型必须在keydown 事件之后、与同一按键相关的keyup事件之前派发。

keypress事件类型必须在beforeinput事件之后、与同一按键相关的input事件之前派发。

支持keypress事件的用户代理的按键事件顺序如下示例:

事件类型 KeyboardEvent
key
InputEvent
data
备注
1 keydown "a"
2 beforeinput "a"
3 keypress "a"
与此按键相关的任何默认行为,如插入字符到DOM等。
4 input
5 keyup "a"

8.4. 传统TextEvent 事件

[Exposed=Window]
interface TextEvent : UIEvent {
    readonly attribute DOMString data;
    undefined initTextEvent(DOMString type,
        optional boolean bubbles = false,
        optional boolean cancelable = false,
        optional Window? view = null,
        optional DOMString data = "undefined");
};

参见UI Events 算法的文本事件部分,了解TextEvent 接口和 textInput事件。

9. 扩展事件

本节为非规范性内容

9.1. 简介

本规范定义了若干接口和许多事件,但并不是为所有目的提供了完整的事件集合。为了让内容作者和实现者能够添加所需功能,且不产生冲突,本规范提供了两种机制来扩展这些接口和事件集:自定义事件实现特定扩展

9.2. 自定义事件

脚本作者可以希望根据功能组件来定义应用程序,并定义对应用架构有意义的事件类型。内容作者可以使用CustomEvent 接口 创建适合其抽象级别的自定义事件。

内容作者可能创建了一个具有动态生成柱状图的应用。该柱状图需要每5分钟更新一次,或者当有新信息推送,或用户点击按钮手动刷新时更新。当图表需要更新时,有多个处理函数需要被调用:应用需要获取最新数据,向用户显示事件正在更新的图标,并重建图表。为此,内容作者可以选择创建一个自定义的updateChart事件,每当触发条件满足时就会派发该事件:
var chartData = ...;
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent( "updateChart", true, false, { data: chartData });
document.documentElement.dispatchEvent(evt);

9.3. 实现特定扩展

设计和原型开发新事件时,或当事件用于实现特定功能时,建议将其与标准化事件区分开来。实现者应为其特定实现的事件类型加上简短前缀,以与其他实现中的同名事件及标准事件区分开。这与CSS中的厂商专用关键字前缀类似,但不使用CSS中的“-”破折号,因为在Javascript属性名中使用时可能产生问题。

某个浏览器厂商FooCorp可能希望引入一个新事件jump。该厂商在其浏览器中实现了fooJump,采用其专用前缀:"foo"。早期用户采用 someElement.addEventListener("fooJump", doJump, false ) 并提供反馈,FooCorp据此调整fooJump行为。

一段时间后,另一家厂商BarOrg也希望实现该功能,但方式略有不同,于是使用自己的前缀"bar",事件类型命名为barJump。内容作者在试验该版本的jump事件时,注册的是BarOrg的事件类型。若内容作者希望兼容两个浏览器,可以分别注册每个事件类型并指定处理函数,或者使用同一个处理函数并通过事件类型名称进行区分。这样,不同代码库中的早期实验不会冲突,且早期用户可以方便地为多种实现编写维护性良好的代码。

最终,随着特性成熟,两个浏览器的行为趋于稳定并可能因内容作者和用户反馈或正式标准化而收敛。此时,冲突风险降低,内容作者可以移除分叉代码,直接使用jump事件类型(甚至在正式标准化之前),采用统一的事件处理方法someElement.addEventListener( "jump", doJump, false)

9.3.1. 已知实现专用前缀

在撰写本文时,已知存在如下事件类型名前缀:

前缀 网页引擎 组织
moz, Moz Gecko Mozilla
ms, MS Trident Microsoft
o, O Presto Opera Software
webkit WebKit Apple, Google, 等

10. 安全注意事项

本附录讨论 UI 事件实现的安全注意事项。讨论仅限于因实现本规范定义的事件模型、API 和事件而直接产生的安全问题。实现通常还支持脚本语言、其他 API 以及本文件未定义的其他事件。这些功能属于未知因素,超出本文档范围。实现者应查阅这些功能规范,了解各自的安全注意事项。

本规范定义的许多事件类型是响应用户行为而派发的。这使得恶意事件监听器能够访问用户通常认为是机密的信息,例如填写表单时可能出现的拼写错误、在提交表单前对多选题答案的犹豫、输入速度或主要输入方式。在最坏情况下,恶意事件监听器可能捕获所有用户交互,并通过 DOM 实现中通常可用的方式(如 XMLHttpRequest 接口)向第三方提交这些信息(这些方式未在本规范中定义)。

在支持加载外部数据的 DOM 实现中,诸如error事件可让应用访问有关计算机系统或网络环境的敏感信息。例如,恶意 HTML 文档试图嵌入本地网络或本地主机的不同端口上的资源。嵌入的 DOM 应用可监听errorload事件,从而判断本地系统可访问哪些网络计算机或哪些端口处于开放状态,为后续攻击做准备。

仅有 UI Events 的实现通常不足以执行此类攻击,相关支持功能的安全注意事项适用。为符合本规范,DOM 实现可采取合理措施,确保 DOM 应用无法访问机密或敏感信息。例如,可以选择不向试图嵌入本地网络资源的节点派发load事件。

11. 致谢

许多人为 DOM 规范(第 1、2 或 3 级)做出了贡献,包括 DOM 工作组、DOM 兴趣组、WebAPI 工作组以及 WebApps 工作组成员。我们特别感谢以下人员:

Andrew Watson (Object Management Group), Andy Heninger (IBM), Angel Diaz (IBM), Anne van Kesteren (Opera Software), Arnaud Le Hors (W3C and IBM), Arun Ranganathan (AOL), Ashok Malhotra (IBM and Microsoft), Ben Chang (Oracle), Bill Shea (Merrill Lynch), Bill Smith (Sun), Björn Höhrmann, Bob Sutor (IBM), Charles McCathie-Nevile (Opera Software, 联合主席), Chris Lovett (Microsoft), Chris Wilson (Microsoft), Christophe Jolif (ILOG), David Brownell (Sun), David Ezell (Hewlett-Packard Company), David Singer (IBM), Dean Jackson (W3C, W3C 团队联系人), Dimitris Dimitriadis (Improve AB 和受邀专家), Don Park (受邀), Doug Schepers (Vectoreal), Elena Litani (IBM), Eric Vasilik (Microsoft), Gavin Nicol (INSO), Gorm Haug Eriksen (Opera Software), Ian Davis (Talis Information Limited), Ian Hickson (Google), Ian Jacobs (W3C), James Clark (受邀), James Davidson (Sun), Jared Sorensen (Novell), Jeroen van Rotterdam (X-Hive Corporation), Joe Kesselman (IBM), Joe Lapp (webMethods), Joe Marini (Macromedia), John Robinson (AOL), Johnny Stenback (Netscape/AOL), Jon Ferraiolo (Adobe), Jonas Sicking (Mozilla Foundation), Jonathan Marsh (Microsoft), Jonathan Robie (Texcel Research and Software AG), Kim Adamson-Sharpe (SoftQuad Software Inc.), Lauren Wood (SoftQuad Software Inc., 前主席), Laurence Cable (Sun), Luca Mascaro (HTML Writers Guild), Maciej Stachowiak (Apple Computer), Marc Hadley (Sun Microsystems), Mark Davis (IBM), Mark Scardina (Oracle), Martin Dürst (W3C), Mary Brady (NIST), Michael Shenfield (Research In Motion), Mick Goulish (Software AG), Mike Champion (Arbortext and Software AG), Miles Sabin (Cromwell Media), Patti Lutsky (Arbortext), Paul Grosso (Arbortext), Peter Sharpe (SoftQuad Software Inc.), Phil Karlton (Netscape), Philippe Le Hégaret (W3C, W3C 团队联系人和前主席), Ramesh Lekshmynarayanan (Merrill Lynch), Ray Whitmer (iMall, Excite@Home, 和 Netscape/AOL, 主席), Rezaur Rahman (Intel), Rich Rollman (Microsoft), Rick Gessner (Netscape), Rick Jelliffe (受邀), Rob Relyea (Microsoft), Robin Berjon (Expway, 联合主席), Scott Hayman (Research In Motion), Scott Isaacs (Microsoft), Sharon Adler (INSO), Stéphane Sire (IntuiLab), Steve Byrne (JavaSoft), Tim Bray (受邀), Tim Yu (Oracle), Tom Pixley (Netscape/AOL), T.V. Raman (Google)。 Vidur Apparao (Netscape) 和 Vinod Anupam (Lucent)。

前任编辑: Tom Pixley(Netscape 通讯公司,至 2002 年 7 月);Philippe Le Hégaret(W3C,至 2003 年 11 月);Björn Höhrmann(受邀专家,至 2008 年 1 月);Jacob Rossi(Microsoft,2011 年 3 月至 2011 年 10 月)。

贡献者: 在 WebApps 工作组中,以下人员对完善和修订本规范作出了重要贡献: Bob Lund(Cable Laboratories), Cameron McCormack(受邀专家 / Mozilla), Daniel Danilatos(Google), Gary Kacmarcik(Google), Glenn Adams(Samsung), Hallvord R. M. Steen(Opera), Hironori Bono(Google), Mark Vickers(Comcast), Masayuki Nakano(Mozilla), Olli Pettay(Mozilla), Takayoshi Kochi(Google)和 Travis Leithead(Microsoft)。

术语表贡献者: Arnaud Le Hors(W3C)和 Robert S. Sutor(IBM Research)。

测试套件贡献者: Carmelo Montanez(NIST), Fred Drake, Mary Brady(NIST), Neil Delima(IBM), Rick Rivello(NIST), Robert Clary(Netscape), 特别鸣谢 Curt Arnold。

感谢所有通过提出建议和修正(请继续向我们反馈问题!)或撰写相关书籍和网站而帮助改进本规范的人士: Al Gilman, Alex Russell, Alexander J. Vincent, Alexey Proskuryakov, Arkadiusz Michalski, Brad Pettit, Cameron McCormack, Chris Rebert, Curt Arnold, David Flanagan, Dylan Schiemann, Erik Arvidsson, Garrett Smith, Giuseppe Pascale, James Su, Jan Goyvaerts(regular-expressions.info), Jorge Chamorro, Kazuyuki Ashimura, Ken Rehor, Magnus Kristiansen, Martijn Wargers, Martin Dürst, Michael B. Allen, Mike Taylor, Misha Wolf, Ojan Vafai, Oliver Hunt, Paul Irish, Peter-Paul Koch, Richard Ishida, Sean Hogan, Sergey Ilinsky, Sigurd Lerstad, Steven Pemberton, Tony Chang, William Edney 和 Øistein E. Andersen。

12. 术语表

以下部分术语定义借鉴或修改自其他 W3C 或标准文档中的类似定义。更多信息请参见定义中的链接。

激活触发器

定义为启动激活行为的事件。

作者

在本规范上下文中,作者内容作者脚本作者是指编写脚本或其他可执行内容、并使用本规范定义的接口、事件和事件流的人。详见§ 1.2.3 内容作者与内容 的一致性类别。

body 元素

在 HTML 或 XHTML 文档中,body 元素表示文档内容。在结构良好的 HTML 文档中,body 元素是根元素的第一个子元素。

字符值

在键值上下文中,字符值是表示一个或多个 Unicode 字符(如字母或符号,或一组字母)的字符串,每个字符属于有效Unicode 字符类别集合。本规范中,字符值以 unicode 字符串(如U+0020)或相同码点的字形表示(如" ")来表示,并用颜色区分这两种表示方式。

在源代码中,一些键值(如非可视字符)可用所用编程语言的字符转义语法表示。

死键

死键是一种键或组合键,本身不产生字符,但与其它键组合或顺序按下时可产生带变音符号的字符(如"ö""é""â")。

默认行为

默认行为是实现必须与事件对象的派发一起执行的可选补充行为。每个事件类型的定义及规范都会定义该事件类型的默认行为(如有)。某些情况下,一个事件实例可能有多个默认行为,如与激活触发器相关时。默认行为可通过调用preventDefault() 方法取消。

delta

用户代理响应支持WheelEvent 接口(如鼠标滚轮或触摸板)的输入设备物理移动,估算页面滚动或缩放的量(以像素、行或页为单位)。delta的值(如deltaXdeltaYdeltaZ属性)应结合当前deltaMode属性解读。滚轮(或其他设备)物理移动与delta正负号的关系依环境和设备而异。但如用户代理以默认行为滚动,则delta的符号按右手坐标系定义,X、Y、Z 轴正方向分别指向文档最右边、最下边、和最远(远离用户)深度。

弃用

被标记为弃用的功能仅为兼容旧实现或规范而保留,在本规范中是可选且不推荐的。只有已有或正在替代的功能才会在本规范中弃用。尚未支持该功能的实现可为兼容现有内容而实现弃用功能,但内容作者新建内容时不应使用弃用功能,除非无其他解决方案。引用本规范的其他规范不应使用弃用功能,应转而引用其替代方案。被弃用的功能预计将在未来规范中被移除。

空字符串

空字符串是长度为0DOMString类型值,即不包含任何字符(无打印字符也无控制字符)的字符串。

事件焦点

事件焦点是对文档中特定元素或其它事件目标的特殊接收与集中状态。每个元素在获得焦点时行为不同,取决于其功能,如激活准备(按钮或链接)、切换状态(复选框)、接收文本输入(文本表单域)或复制选中文本。详见§ 3.3.3 文档焦点与焦点上下文

事件焦点环

事件焦点环是文档中一组有序的事件焦点目标。宿主语言可定义一种或多种目标排序方式,如文档顺序、每个焦点目标的数值索引、焦点目标间的显式指针或多种模型的混合。每个文档可包含多个焦点环或条件焦点环。通常,文档顺序或索引型焦点环会使焦点从最后一个目标“环回”到第一个目标。

事件目标

通过事件流将事件指向的对象。事件目标即target属性的值。

事件类型

事件类型是具有特定名称的事件对象,定义了具体触发条件、属性及其它区分于其他事件类型的特征。例如,click事件类型与mouseoverload事件类型特征不同。事件类型通过事件对象上的type属性暴露。也可泛称为“事件”,如click事件

宿主语言

集成其它语言或 API 规范特性,同时规范性引用原规范而非重定义这些特性,并仅按原规范定义方式扩展这些特性的语言。原规范通常仅打算在一个或多个宿主语言上下文中实现,而非作为独立语言。例如,XHTML、HTML 和 SVG 都是 UI Events 的宿主语言,集成并扩展本规范定义的对象和模型。

迟滞

人机界面设计中的一个特性,允许输入值在一定位置或时间范围内被接受,以提升用户体验。例如,允许用户双击鼠标按钮的时间略有偏差属于时间迟滞,用户从父窗口鼠标移出到子菜单时不立即关闭嵌套菜单属于位置迟滞。

IME
输入法编辑器

输入法编辑器(IME),也称前端处理器,是一种应用程序,负责将键盘输入转换为表意文字或其它字符,通常通过用户引导的词典查找实现,常用于东亚语言(如中文、日文、韩文)。IME也可用于基于词典的单词补全,如移动设备。有关 IME 的规范处理,参见§ 4.3.3 输入法编辑器。另见文本输入系统

按键映射

按键映射是为特定按键分配键值的过程,结果受多种因素影响,包括操作系统和键盘布局(如QWERTY、Dvorak、西班牙语、InScript、中文等),以及所有修饰键ShiftAlt等)和死键状态。

按键值

按键值是字符值或多字符字符串(如"Enter""Tab""MediaTrackNext"),对应于特定状态下的按键。每个按键都有按键值,无论其是否有字符值,包括控制键、功能键、修饰键死键及其它按键。任意按键在任意时刻的按键值取决于按键映射

修饰键

修饰键改变按键的正常行为,如输出不同大小写字符(如Shift键)、或改变按键触发的功能(如FnAlt键)。详见§ 4.3.1 修饰键修饰键表,可查阅所有有效修饰键。

命名空间 URI

命名空间 URI是标识 XML 命名空间的 URI。在[XML-Names11]中称为命名空间名称。有关 URI 及命名空间 URI 在 DOM API 中的处理与比较,详见第 1.3.2 节DOM URI和第 1.3.3 节XML 命名空间

QWERTY

QWERTY(发音为ˈkwɜrti)是一种常见键盘布局,因字母键顶行前五个字符键为 Q、W、E、R、T、Y 而得名。还有许多其他流行键盘布局(如 Dvorak、Colemak),多数为本地化或人体工学设计。

根元素

文档中的第一个元素节点,所有其他元素都是其子元素。即文档元素。

旋转

使用WheelEvent 接口的输入设备上的增量变化指示。在某些设备上可能是轮的实际旋转,或在其他设备上为平面上的移动,或对特定按钮的压力。

文本输入系统

将某种替代输入(如输入法编辑器、语音处理器或手写识别系统)解释并转换为文本的软件组件。

最顶层事件目标

最顶层事件目标必须是渲染顺序中最高、且能成为事件目标的元素。在图形界面中即为用户指针设备下的元素。用户界面的命中测试用于确定目标。有关命中测试和堆叠顺序的细节,见宿主语言

Unicode 字符类别

为每个 Unicode 码点定义的一般类别值的子集。该子集包含所有 字母(LlLmLoLtLu)、 数字(NdNlNo)、 标点(PcPdPePfPiPoPs) 和符号(ScSkSmSo) 类别值。

未初始化值

事件属性(如bubblescurrentTarget)在事件用initEvent()初始化前的值。事件的未初始化值在用createEvent()方法新建事件后立即生效。

一致性

文档约定

一致性要求通过描述性断言和 RFC 2119 术语的组合表达。 规范性部分中的关键词“MUST”(必须)、“MUST NOT”(不得)、“REQUIRED”(要求)、“SHALL”(应)、“SHALL NOT”(不应)、“SHOULD”(建议)、“SHOULD NOT”(不建议)、“RECOMMENDED”(推荐)、“MAY”(可以)、“OPTIONAL”(可选), 均应按照 RFC 2119 的说明进行解释。 但为了可读性,本规范未将这些词全部大写。

除明确标记为非规范性、示例和注释的章节外,本规范的所有文本均为规范性内容。[RFC2119]

本规范中的示例以“例如”开头,或通过class="example"与规范性文本区分,如下所示:

这是一个说明性示例。

说明性注释以“注”开头,并通过class="note"与规范性文本区分,如下所示:

注:这是一个说明性注释。

一致性算法

作为算法一部分,以祈使语气表达的要求(如“去除所有前导空格字符”或“返回 false 并终止这些步骤”)应按照引入该算法时使用的关键词(“must”、“should”、“may”等)解释。

以算法或具体步骤表达的一致性要求,可以采用任何实现方式,只要最终结果等效即可。 特别是,本规范中定义的算法旨在易于理解,并非为了性能优化。 鼓励实现者进行优化。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[CSS-COLOR-3]
Tantek Çelik; Chris Lilley; David Baron. CSS颜色模块第3级。2022年1月18日。REC。网址:https://www.w3.org/TR/css-color-3/
[CSS2]
Bert Bos 等。层叠样式表第2级修订版(CSS 2.1)规范。2011年6月7日。REC。网址:https://www.w3.org/TR/CSS21/
[CSSOM-View]
Simon Pieters。CSSOM视图模块。2016年3月17日。WD。网址:https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren。DOM标准。实时标准。网址:https://dom.spec.whatwg.org/
[DOM-Level-3-Core]
Arnaud Le Hors 等。文档对象模型(DOM)第3级核心规范。2021年9月28日。REC。网址:https://www.w3.org/TR/DOM-Level-3-Core/
[HTML]
Anne van Kesteren 等。HTML标准。实时标准。网址:https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola。基础设施标准。实时标准。网址:https://infra.spec.whatwg.org/
[PointerEvents3]
Patrick Lauke; Robert Flack。指针事件。2024年8月14日。WD。网址:https://www.w3.org/TR/pointerevents3/
[POINTERLOCK-2]
Mustaq Ahmed; Vincent Scheib。Pointer Lock 2.0。2024年6月17日。WD。网址:https://www.w3.org/TR/pointerlock-2/
[RFC2119]
S. Bradner。用于在RFC中指示需求等级的关键词。1997年3月。最佳当前实践。网址:https://datatracker.ietf.org/doc/html/rfc2119
[UIEvents-Code]
Travis Leithead; Gary Kacmarcik。UI事件KeyboardEvent代码值。2023年5月30日。CR。网址:https://www.w3.org/TR/uievents-code/
[UIEvents-Key]
Travis Leithead; Gary Kacmarcik。UI事件KeyboardEvent键值。2023年5月30日。CR。网址:https://www.w3.org/TR/uievents-key/
[WebIDL]
Edgar Chen; Timothy Gu。Web IDL标准。实时标准。网址:https://webidl.spec.whatwg.org/

参考性引用

[DWW95]
N. Kano。为Windows 95和Windows NT开发国际软件:国际软件设计手册。1995年。
[Editing]
A. Gregor。HTML编辑API。网址:https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html
[HTML401]
Dave Raggett; Arnaud Le Hors; Ian Jacobs。HTML 4.01规范。2018年3月27日。REC。网址:https://www.w3.org/TR/html401/
[HTML5]
Ian Hickson 等。HTML5。2018年3月27日。REC。网址:https://www.w3.org/TR/html5/
[Input-Events]
Johannes Wilm。输入事件第1级。2023年9月28日。WD。网址:https://www.w3.org/TR/input-events-1/
[PointerLock]
Vincent Scheib。Pointer Lock。2016年10月27日。REC。网址:https://www.w3.org/TR/pointerlock/
[RFC20]
V.G. Cerf。用于网络交换的ASCII格式。1969年10月。互联网标准。网址:https://www.rfc-editor.org/rfc/rfc20
[UAAG20]
James Allan 等。用户代理可访问性指南(UAAG)2.0。2015年12月15日。NOTE。网址:https://www.w3.org/TR/UAAG20/
[UAX15]
Ken Whistler。Unicode规范化形式。2023年8月12日。Unicode标准附件#15。网址:https://www.unicode.org/reports/tr15/tr15-54.html
[Unicode]
Unicode标准。网址:https://www.unicode.org/versions/latest/
[US-ASCII]
编码字符集 - 7位美国标准信息交换码。1986年。
[WIN1252]
Windows 1252 编码字符集 - 8位。网址:https://www.microsoft.com/globaldev/reference/sbcs/1252.htm
[XFORMS11]
John Boyer。XForms 1.1。2009年10月20日。REC。网址:https://www.w3.org/TR/xforms11/
[XML]
Tim Bray 等。可扩展标记语言(XML)1.0(第五版)。2008年11月26日。REC。网址:https://www.w3.org/TR/xml/
[XML-Names11]
Tim Bray 等。XML 1.1名称空间(第二版)。2006年8月16日。REC。网址:https://www.w3.org/TR/xml-names11/

IDL索引

[Exposed=Window]
interface UIEvent : Event {
  constructor(DOMString type, optional UIEventInit eventInitDict = {});
  readonly attribute Window? view;
  readonly attribute long detail;
};

dictionary UIEventInit : EventInit {
  Window? view = null;
  long detail = 0;
};

[Exposed=Window]
interface FocusEvent : UIEvent {
  constructor(DOMString type, optional FocusEventInit eventInitDict = {});
  readonly attribute EventTarget? relatedTarget;
};

dictionary FocusEventInit : UIEventInit {
  EventTarget? relatedTarget = null;
};

[Exposed=Window]
interface MouseEvent : UIEvent {
  constructor(DOMString type, optional MouseEventInit eventInitDict = {});
  readonly attribute long screenX;
  readonly attribute long screenY;
  readonly attribute long clientX;
  readonly attribute long clientY;
  readonly attribute long layerX;
  readonly attribute long layerY;

  readonly attribute boolean ctrlKey;
  readonly attribute boolean shiftKey;
  readonly attribute boolean altKey;
  readonly attribute boolean metaKey;

  readonly attribute short button;
  readonly attribute unsigned short buttons;

  readonly attribute EventTarget? relatedTarget;

  boolean getModifierState(DOMString keyArg);
};

dictionary MouseEventInit : EventModifierInit {
  long screenX = 0;
  long screenY = 0;
  long clientX = 0;
  long clientY = 0;

  short button = 0;
  unsigned short buttons = 0;
  EventTarget? relatedTarget = null;
};

dictionary EventModifierInit : UIEventInit {
  boolean ctrlKey = false;
  boolean shiftKey = false;
  boolean altKey = false;
  boolean metaKey = false;

  boolean modifierAltGraph = false;
  boolean modifierCapsLock = false;
  boolean modifierFn = false;
  boolean modifierFnLock = false;
  boolean modifierHyper = false;
  boolean modifierNumLock = false;
  boolean modifierScrollLock = false;
  boolean modifierSuper = false;
  boolean modifierSymbol = false;
  boolean modifierSymbolLock = false;
};

[Exposed=Window]
interface WheelEvent : MouseEvent {
  constructor(DOMString type, optional WheelEventInit eventInitDict = {});
  // DeltaModeCode
  const unsigned long DOM_DELTA_PIXEL = 0x00;
  const unsigned long DOM_DELTA_LINE  = 0x01;
  const unsigned long DOM_DELTA_PAGE  = 0x02;

  readonly attribute double deltaX;
  readonly attribute double deltaY;
  readonly attribute double deltaZ;
  readonly attribute unsigned long deltaMode;
};

dictionary WheelEventInit : MouseEventInit {
  double deltaX = 0.0;
  double deltaY = 0.0;
  double deltaZ = 0.0;
  unsigned long deltaMode = 0;
};

[Exposed=Window]
interface InputEvent : UIEvent {
  constructor(DOMString type, optional InputEventInit eventInitDict = {});
  readonly attribute USVString? data;
  readonly attribute boolean isComposing;
  readonly attribute DOMString inputType;
};

dictionary InputEventInit : UIEventInit {
  DOMString? data = null;
  boolean isComposing = false;
  DOMString inputType = "";
};

[Exposed=Window]
interface KeyboardEvent : UIEvent {
  constructor(DOMString type, optional KeyboardEventInit eventInitDict = {});
  // KeyLocationCode
  const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00;
  const unsigned long DOM_KEY_LOCATION_LEFT = 0x01;
  const unsigned long DOM_KEY_LOCATION_RIGHT = 0x02;
  const unsigned long DOM_KEY_LOCATION_NUMPAD = 0x03;

  readonly attribute DOMString key;
  readonly attribute DOMString code;
  readonly attribute unsigned long location;

  readonly attribute boolean ctrlKey;
  readonly attribute boolean shiftKey;
  readonly attribute boolean altKey;
  readonly attribute boolean metaKey;

  readonly attribute boolean repeat;
  readonly attribute boolean isComposing;

  boolean getModifierState(DOMString keyArg);
};

dictionary KeyboardEventInit : EventModifierInit {
  DOMString key = "";
  DOMString code = "";
  unsigned long location = 0;
  boolean repeat = false;
  boolean isComposing = false;
};

[Exposed=Window]
interface CompositionEvent : UIEvent {
  constructor(DOMString type, optional CompositionEventInit eventInitDict = {});
  readonly attribute USVString data;
};

dictionary CompositionEventInit : UIEventInit {
  DOMString data = "";
};

partial interface UIEvent {
  // Deprecated in this specification
  undefined initUIEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional Window? viewArg = null,
    optional long detailArg = 0);
};

partial interface MouseEvent {
  // Deprecated in this specification
  undefined initMouseEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional Window? viewArg = null,
    optional long detailArg = 0,
    optional long screenXArg = 0,
    optional long screenYArg = 0,
    optional long clientXArg = 0,
    optional long clientYArg = 0,
    optional boolean ctrlKeyArg = false,
    optional boolean altKeyArg = false,
    optional boolean shiftKeyArg = false,
    optional boolean metaKeyArg = false,
    optional short buttonArg = 0,
    optional EventTarget? relatedTargetArg = null);
};

partial interface KeyboardEvent {
  // Originally introduced (and deprecated) in this specification
  undefined initKeyboardEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional Window? viewArg = null,
    optional DOMString keyArg = "",
    optional unsigned long locationArg = 0,
    optional boolean ctrlKey = false,
    optional boolean altKey = false,
    optional boolean shiftKey = false,
    optional boolean metaKey = false);
};

partial interface CompositionEvent {
  // Originally introduced (and deprecated) in this specification
  undefined initCompositionEvent(DOMString typeArg,
    optional boolean bubblesArg = false,
    optional boolean cancelableArg = false,
    optional WindowProxy? viewArg = null,
    optional DOMString dataArg = "");
};

partial interface UIEvent {
  // The following support legacy user agents
  readonly attribute unsigned long which;
};

partial dictionary UIEventInit {
  unsigned long which = 0;
};

partial interface KeyboardEvent {
  // The following support legacy user agents
  readonly attribute unsigned long charCode;
  readonly attribute unsigned long keyCode;
};

partial dictionary KeyboardEventInit {
  // The following support legacy user agents
  unsigned long charCode = 0;
  unsigned long keyCode = 0;
};

[Exposed=Window]
interface TextEvent : UIEvent {
    readonly attribute DOMString data;
    undefined initTextEvent(DOMString type,
        optional boolean bubbles = false,
        optional boolean cancelable = false,
        optional Window? view = null,
        optional DOMString data = "undefined");
};

问题索引

参见UI事件算法中的文本事件部分,了解 TextEvent接口和 textInput事件。
MDN

CompositionEvent/CompositionEvent

In all current engines.

Firefox53+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CompositionEvent/data

In all current engines.

Firefox9+Safari5+Chrome15+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari5+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

CompositionEvent

In all current engines.

Firefox9+Safari5+Chrome15+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari5+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Element/auxclick_event

Firefox53+SafariNoneChrome55+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android53+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Element/blur_event

In all current engines.

Firefox24+Safari3.1+Chrome1+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+

Window/blur_event

In all current engines.

Firefox6+Safari5.1+Chrome5+
Opera12.1+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/click_event

In all current engines.

Firefox6+Safari3+Chrome1+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android6+iOS Safari1+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

Element/compositionend_event

In all current engines.

Firefox9+Safari5+Chrome15+
Opera15+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari5+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile14+
MDN

Element/compositionstart_event

In all current engines.

Firefox9+Safari5+Chrome15+
Opera15+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari5+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile14+
MDN

Element/compositionupdate_event

In all current engines.

Firefox9+Safari5+Chrome18+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari5+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

Element/contextmenu_event

In all current engines.

Firefox6+Safari3+Chrome1+
Opera10.5+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS SafariNoneChrome for Android?Android WebView?Samsung Internet?Opera Mobile11.1+
MDN

Element/dblclick_event

In all current engines.

Firefox6+Safari3+Chrome1+
Opera11.6+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android6+iOS Safari1+Chrome for AndroidNoneAndroid WebView?Samsung Internet?Opera Mobile12.1+
MDN

Element/focus_event

In all current engines.

Firefox24+Safari3.1+Chrome1+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+

Window/focus_event

In all current engines.

Firefox6+Safari5.1+Chrome5+
Opera12.1+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/focusin_event

In all current engines.

Firefox52+Safari5+Chrome1+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/focusout_event

In all current engines.

Firefox52+Safari5+Chrome1+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/keydown_event

In all current engines.

Firefox6+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

Element/keyup_event

In all current engines.

Firefox6+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

Element/mousedown_event

In all current engines.

Firefox6+Safari4+Chrome2+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/mouseenter_event

In all current engines.

Firefox10+Safari7+Chrome30+
Opera?Edge79+
Edge (Legacy)12+IE5.5+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

Element/mouseleave_event

In all current engines.

Firefox10+Safari7+Chrome30+
Opera?Edge79+
Edge (Legacy)12+IE5.5+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

Element/mousemove_event

In all current engines.

Firefox6+Safari4+Chrome2+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/mouseout_event

In all current engines.

Firefox6+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/mouseover_event

In all current engines.

Firefox6+Safari4+Chrome2+
Opera9.5+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile10.1+
MDN

Element/mouseup_event

In all current engines.

Firefox6+Safari4+Chrome2+
Opera11.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Element/wheel_event

In all current engines.

Firefox17+Safari7+Chrome31+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS SafariNoneChrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FocusEvent/FocusEvent

In all current engines.

Firefox24+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FocusEvent/relatedTarget

In all current engines.

Firefox24+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FocusEvent

In all current engines.

Firefox24+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

HTMLElement/beforeinput_event

In all current engines.

Firefox87+Safari10.1+Chrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

HTMLElement/error_event

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

HTMLElement/input_event

In all current engines.

Firefox6+Safari3.1+Chrome1+
Opera11.6+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12+
MDN

InputEvent/InputEvent

Firefox31+SafariNoneChrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

InputEvent/inputType

In all current engines.

Firefox66+Safari10.1+Chrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

InputEvent/isComposing

In all current engines.

Firefox31+Safari16.4+Chrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

InputEvent

In all current engines.

Firefox31+Safari10.1+Chrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/KeyboardEvent

In all current engines.

Firefox31+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/altKey

In all current engines.

Firefox1.5+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

KeyboardEvent/code

In all current engines.

Firefox38+Safari10.1+Chrome48+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/ctrlKey

In all current engines.

Firefox1.5+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

KeyboardEvent/getModifierState

In all current engines.

Firefox15+Safari10.1+Chrome30+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/isComposing

In all current engines.

Firefox31+Safari10.1+Chrome56+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/key

In all current engines.

Firefox23+Safari10.1+Chrome51+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/location

In all current engines.

Firefox15+Safari8+Chrome30+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/metaKey

In all current engines.

Firefox1.5+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

KeyboardEvent/repeat

In all current engines.

Firefox28+Safari10.1+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

KeyboardEvent/shiftKey

In all current engines.

Firefox1.5+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

KeyboardEvent

In all current engines.

Firefox1.5+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/MouseEvent

In all current engines.

Firefox11+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

MouseEvent/altKey

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/button

In all current engines.

Firefox1+Safari1+Chrome1+
Opera10.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
MDN

MouseEvent/buttons

In all current engines.

Firefox15+Safari11.1+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android15+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

MouseEvent/clientX

In all current engines.

Firefox1+Safari1+Chrome1+
Opera10.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
MDN

MouseEvent/clientY

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/ctrlKey

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/getModifierState

In all current engines.

Firefox15+Safari12.1+Chrome47+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

MouseEvent/metaKey

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/relatedTarget

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/screenX

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/screenY

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent/shiftKey

In all current engines.

Firefox1.5+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

MouseEvent

In all current engines.

Firefox1+Safari1+Chrome1+
Opera10.6+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
MDN

UIEvent/UIEvent

In all current engines.

Firefox11+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView1+Samsung Internet1.0+Opera Mobile?
MDN

UIEvent/detail

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

UIEvent/view

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

UIEvent

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

WheelEvent/WheelEvent

In all current engines.

Firefox17+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet1.0+Opera Mobile?
MDN

WheelEvent/deltaMode

In all current engines.

Firefox17+Safari7+Chrome26+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet1.0+Opera Mobile?
MDN

WheelEvent/deltaX

In all current engines.

Firefox17+Safari8+Chrome31+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

WheelEvent/deltaY

In all current engines.

Firefox17+Safari8+Chrome31+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

WheelEvent/deltaZ

In all current engines.

Firefox17+Safari8+Chrome31+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

WheelEvent

In all current engines.

Firefox17+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari1+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

Window/load_event

In all current engines.

Firefox1+Safari1.3+Chrome1+
Opera4+Edge79+
Edge (Legacy)12+IE4+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile10.1+