1. 介绍
1.1. 概述
UI Events 设计有两个主要目标。第一个目标是设计一个 事件 系统,该系统允许注册 事件监听器, 并描述事件在树结构中的流动方式。此外,本规范将为用户界面控制和文档变更通知提供标准事件模块,并为这些事件模块定义相关的上下文信息。
UI Events 的第二个目标是提供当前主流浏览器所用事件系统的通用子集,旨在促进现有脚本和内容的互操作性。并不期望该目标能实现完全的向后兼容,但规范会在可能时予以实现。
1.1.1. 鼠标与滚轮事件
本规范中的鼠标事件和滚轮事件部分已移至 Pointer Events 规范 [pointerevents4]。
1.2. 一致性
本节为规范性内容。
在本规范中,关键词 MUST
、MUST NOT
、REQUIRED
、SHALL
、SHALL
NOT
、SHOULD
、SHOULD NOT
、RECOMMENDED
、MAY
与 OPTIONAL
应按 [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 的要求,如果其支持:
-
[DOM-Level-3-Core] 中定义的 Core 模块
-
本规范中定义的所有接口和事件及其相关方法、属性和语义,除标记为 弃用 的部分(符合要求的用户代理可为兼容旧内容实现弃用的接口、事件或 API,但并非必须实现才能符合要求)
-
UI Events KeyboardEvent key 值与 code 值规范 [UIEvents-Key] 及 [UIEvents-Code] 中定义的所有
key与code值(视平台可用性而定) -
本规范中定义的所有其他规范性要求。
符合要求的浏览器在满足某 事件分发 的条件时,必须将事件分发至相应的
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 规范建议约定, 并补充如下:
-
印在按键上的 键帽 显示为
↓、=或Q。用于从用户角度引用按键,而不考虑生成的key和code在KeyboardEvent中的值。 -
表示字符的字形显示为:
"𣧂"。 -
Unicode 字符编码显示为:
U+003d。 -
按键按下生成的按键值名称(即
KeyboardEvent.key的值)显示为:"ArrowDown"、"="、"q"或"Q"。 -
与物理按键相关的按键代码名称(即
KeyboardEvent.code的值)显示为:"ArrowDown"、"Equal"或"KeyQ"。
此外,本规范中某些术语有特定含义。术语 实现
指实现本规范的浏览器、内容创作工具或其他 用户代理,
而内容作者是指编写脚本或代码、利用规范中描述的接口、方法、属性、事件和其他特性来创建 Web 应用的人员,用户则是指在实现中使用这些 Web 应用的人。
最后:
这是一个备注。
这是一个未解决的问题。
这是一个警告。
interface Example {
// 这是一个 IDL 定义。
};
3. 基础事件接口
[DOM] 中定义的基础事件接口是 UI Events 的基础。这些基础事件接口在实现中必须始终被支持:
-
Event接口及其以下常量、方法和属性:-
NONE常量 -
AT_TARGET常量 -
type属性 -
target属性 -
eventPhase属性 -
bubbles属性 -
cancelable属性 -
composed属性 -
timeStamp属性 -
isTrusted属性 -
initEvent()方法
-
-
CustomEvent接口及其以下方法和属性:-
detail属性
-
EventTarget接口及其以下方法: -
EventListener接口及其handleEvent()方法 -
Document接口的createEvent()方法
本规范定义的事件类型均派生自上述基础接口,且必须继承其所有属性、方法和常量。
下图描述了本规范所述接口的继承关系结构。
3.1. 事件类型列表
每个事件必须关联一个类型,称为事件类型,可通过事件对象的 type
属性获取。事件类型必须为 DOMString 类型。
根据 DOM 支持级别或用于显示(如屏幕)或交互(如鼠标、键盘、触摸屏或语音)的设备,事件类型可由实现生成。当与 [XML] 或 [HTML5] 应用配合使用时,这些语言的规范可能会限制事件类型的语义和作用范围(尤其是可能的 事件目标)。请参阅所用语言的规范以获取这些限制或查找未在本文件中定义的事件类型。
下表为本规范所述事件类型的说明性摘要。
| 事件类型 | 同步 / 异步 | 冒泡阶段 | 可信事件目标类型 | DOM 接口 | 可取消 | 默认行为 |
|---|---|---|---|---|---|---|
abort
| 同步 | 否 | 窗口, 元素 | Event
| 否 | 无 |
beforeinput
| 同步 | 是 | 元素 | InputEvent
| 是 | 更新 DOM 元素 |
blur
| 同步 | 否 | 窗口, 元素 | FocusEvent
| 否 | 无 |
compositionstart
| 同步 | 是 | 元素 | CompositionEvent
| 是 | 显示文本输入系统候选窗口 |
compositionupdate
| 同步 | 是 | 元素 | CompositionEvent
| 否 | 无 |
compositionend
| 同步 | 是 | 元素 | CompositionEvent
| 否 | 无 |
error
| 异步 | 否 | 窗口, 元素 | Event
| 否 | 无 |
focus
| 同步 | 否 | 窗口, 元素 | FocusEvent
| 否 | 无 |
focusin
| 同步 | 是 | 窗口, 元素 | FocusEvent
| 否 | 无 |
focusout
| 同步 | 是 | 窗口, 元素 | FocusEvent
| 否 | 无 |
input
| 同步 | 是 | 元素 | InputEvent
| 否 | 无 |
keydown
| 同步 | 是 | 元素 | KeyboardEvent
| 是 | 不同:触发 beforeinput 和 input 事件;启动 文本输入系统;blur 和 focus 事件;keypress
事件(如支持);激活行为;其他事件
|
keyup
| 同步 | 是 | 元素 | KeyboardEvent
| 是 | 无 |
load
| 异步 | 否 | 窗口, 文档, 元素 | Event
| 否 | 无 |
select
| 同步 | 是 | 元素 | Event
| 否 | 无 |
unload
| 同步 | 否 | 窗口, 文档, 元素 | Event
| 否 | 无 |
关于本规范中弃用事件列表,请见文末附录旧版事件类型。
以下是对上表的一种解读方式:load 事件会在 Element
节点的捕获和目标阶段触发为该事件注册的 事件监听器。该事件不可取消。如果为 load 事件在 Window、Document 或 Element
节点之外的节点注册事件监听器,或者仅注册在冒泡阶段,则该 事件监听器不会被触发。
不要将上表视为所有列出事件类型的权威说明。例如,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 = 0; };detail
UIEventInit . view- 应初始化为该事件将被分发的全局环境的 Window 对象。如果事件将分发到某元素,则 view 属性应设为包含该元素
ownerDocument的 Window 对象。 UIEventInit . detail- 此值初始化为应用相关的数字。
3.2.2. UIEvent 算法
3.2.2.1. 初始化 UIEvent
- 输入
-
event,要初始化的
UIEventeventType,包含事件类型的 DOMString
eventTarget,事件的
EventTargetbubbles,如果该事件可冒泡则为 true
cancelable,如果该事件可取消则为 true
- 输出
-
无
-
初始化基础
Event属性: -
初始化以下公开属性:
-
初始化以下历史属性:
-
将 event.
which设置为 0(用于MouseEvent和KeyboardEvent)
-
3.2.3. UIEvent 类型
用户界面事件类型如下所列。其中一些事件如果由用户界面生成,则使用 UIEvent 接口,否则使用
Event
接口,具体见各事件说明。
3.2.3.1. load
| 类型 | load
|
|---|---|
| 接口 | UIEvent
(由用户界面生成时),否则为 Event。
|
| 同步 / 异步 | 异步 |
| 冒泡 | 否 |
| 可信目标 | Window、Document、Element
|
| 可取消 | 否 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当 DOM 实现完成资源(如文档)及其任何依赖资源(如图片、样式表或脚本)加载时,用户代理必须分发该事件。未能成功加载的依赖资源不会阻止该事件触发,只要加载它们的资源仍可通过 DOM
访问。如果分发了该事件类型,要求实现至少在 Document 节点上分发该事件。
出于兼容旧版的原因,文档内部资源(如图片)的 load 事件在 HTML 实现中不会包含 Window 于传播路径。更多信息见 [HTML5]。
3.2.3.2. unload
| 类型 | unload
|
|---|---|
| 接口 | UIEvent
(由用户界面生成时),否则为 Event。
|
| 同步 / 异步 | 同步 |
| 冒泡 | 否 |
| 可信目标 | Window、Document、Element
|
| 可取消 | 否 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当 DOM 实现从环境中移除资源(如文档)或任何依赖资源(如图片、样式表、脚本)时,用户代理必须分发该事件。该事件类型分发后,文档必须被卸载。如果分发了该事件类型,要求实现至少在 Document
节点上分发该事件。
3.2.3.3. abort
| 类型 | abort
|
|---|---|
| 接口 | UIEvent
(由用户界面生成时),否则为 Event。
|
| 同步 / 异步 | 同步 |
| 冒泡 | 否 |
| 可信目标 | Window、Element
|
| 可取消 | 否 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当某资源加载被中止(如用户在加载过程中取消加载),用户代理必须分发该事件。
3.2.3.4. error
| 类型 | error
|
|---|---|
| 接口 | UIEvent
(由用户界面生成时),否则为 Event。
|
| 同步 / 异步 | 异步 |
| 冒泡 | 否 |
| 可信目标 | Window、Element
|
| 可取消 | 否 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当某资源加载失败,或已加载但无法根据语义解释(如图片无效、脚本执行错误或 XML 非格式良好),用户代理必须分发该事件。
3.2.3.5. select
| 类型 | select
|
|---|---|
| 接口 | UIEvent
(由用户界面生成时),否则为 Event。
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 可信目标 | Element
|
| 可取消 | 否 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当用户选择了某些文本后,用户代理必须分发该事件。该事件在选择行为发生后分发。
本规范不提供访问选中文本的上下文信息。适用时,应由 宿主语言定义用户如何选择内容(要考虑国际语言惯例)、select 事件分发的时机,以及内容作者如何访问用户选中的内容。
内容作者要访问用户选中的内容,可使用 宿主语言的原生能力,例如 HTML 编辑 API 的 Document.getSelection() 方法
[Editing]。
select 事件未必在所有语言的所有元素上都可用。例如,在 [HTML5] 中,select 事件仅可在表单
input
和
textarea
元素上分发。实现可在任何认为合适的上下文分发 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应初始化为失去焦点的元素(用于focus或focusin事件)或获得焦点的元素(用于blur或focusout事件)。
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 键会将焦点切换到第三个元素。宿主语言可以定义哪些元素可以获得焦点、元素可获得焦点的条件、焦点切换的方式及顺序。例如,某些情况下可通过指针悬停获得焦点,其他情况则需鼠标点击。有些元素可能根本不可获得焦点,有些只可通过特定方式(如点击)获得,而不可 Tab 切换。文档可包含多个焦点环。其他规范可以定义比本规范更复杂的焦点模型,包括允许多个元素同时获得当前焦点。
3.3.4. 焦点事件类型
焦点事件类型如下所列。
3.3.4.1. blur
| 类型 | blur
|
|---|---|
| 接口 | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 否 |
| 可信目标 | Window, Element
|
| 可取消 | 否 |
| 组合 | 是 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当一个 用户代理 必须在 事件目标 失去焦点时派发此事件。焦点必须在派发该事件类型前从元素移除。此事件类型类似于 focusout,但不会冒泡。
3.3.4.2. focus
| 类型 | focus
|
|---|---|
| 接口 | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 否 |
| 可信目标 | Window, Element
|
| 可取消 | 否 |
| 组合 | 是 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当一个 用户代理 必须在 事件目标 获得焦点时派发此事件。焦点必须在派发该事件类型前赋予该元素。此事件类型类似于 focusin,但不会冒泡。
3.3.4.3. focusin
| 类型 | focusin
|
|---|---|
| 接口 | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 可信目标 | Window, Element
|
| 可取消 | 否 |
| 组合 | 是 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当一个 用户代理 必须在 事件目标 获得焦点时派发此事件。事件目标 必须是获得焦点的元素。在派发该事件类型之前,必须先触发 focus 事件。此事件类型类似于 focus,但会冒泡。
3.3.4.4. focusout
| 类型 | focusout
|
|---|---|
| 接口 | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 可信目标 | Window, Element
|
| 可取消 | 否 |
| 组合 | 是 |
| 默认行为 | 无 |
| 上下文 (可信事件) |
当一个 用户代理 必须在 事件目标 失去焦点时派发此事件。事件目标 必须是失去焦点的元素。在派发该事件类型之前,必须先触发 blur 事件。此事件类型类似于 blur,但会冒泡。
3.4. 输入事件
输入事件在 DOM 因用户操作(例如,可编辑区域的键盘输入、删除或格式化文本等)而被更新(或即将被更新)时作为通知发送。
3.4.1. 接口 InputEvent
3.4.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,只读,可为空-
data保存由输入法生成的字符值。它可以是单个 Unicode 字符,或是一个非空的 Unicode 字符序列 [Unicode]。字符应按 Unicode 规范中的规范化形式 NFC 进行规范化,参考 [UAX15]。 该属性也可以包含空字符串。该属性的未初始化值 必须为
null。 isComposing, 类型为 boolean,只读-
如果输入事件发生在合成会话期间,即在对应的
compositionstart事件之后且在对应的compositionend事件之前,则该值为true。该属性的未初始化值 必须为
false。 inputType, 类型为 DOMString,只读-
inputType包含一个字符串,用于标识与该事件相关的输入类型。有关此属性的有效值列表,请参阅 [Input-Events] 规范。
该属性的未初始化值 必须为空字符串
""。
3.4.1.2. InputEventInit
dictionary :InputEventInit UIEventInit {DOMString ?data =null ;boolean isComposing =false ;DOMString inputType = ""; };
data, 类型为 DOMString,可为空,默认为null-
用于初始化 InputEvent 对象的
data属性。 isComposing, 类型为 boolean,默认为false-
用于初始化 InputEvent 对象的
isComposing属性。 inputType, 类型为 DOMString,默认为""-
用于初始化 InputEvent 对象的
inputType属性。
3.4.2. 输入事件顺序
本规范中定义的输入事件必须以固定顺序相互发生。
| 事件类型 | 备注 | |
|---|---|---|
| 1 | beforeinput
| |
| DOM 元素将被更新 | ||
| 2 | input
|
3.4.3. 输入事件类型
3.4.3.1. beforeinput
| 类型 | beforeinput
|
|---|---|
| 接口 | InputEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Element(具体而言:诸如 HTMLInputElement 等控件类型)或任何启用了
contenteditable 属性的 Element
|
| 可取消 | 是 |
| 组合 | 是 |
| 默认动作 | 更新 DOM 元素 |
| 上下文 (受信任事件) |
|
用户代理必须在 DOM 即将被更新时派发此事件。
3.4.3.2. input
| 类型 | input
|
|---|---|
| 接口 | InputEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Element(具体而言:诸如 HTMLInputElement 等控件类型)或任何启用了
contenteditable 属性的 Element
|
| 可取消 | 否 |
| 可组成 | 是 |
| 默认动作 | 无 |
| 上下文 (受信任事件) |
|
用户代理必须在 DOM 更新之后立即派发此事件。
3.5. 键盘事件
键盘事件依赖于设备,也就是说它们依赖于输入设备的能力以及操作系统中的映射方式。有关更多细节,请参阅 键盘事件和键值,其中包括关于如何将键盘事件与合成事件结合使用的示例。根据字符生成设备,可能不会生成键盘事件。
键盘事件只是提供文本输入的一种方式。对于编辑场景,也可以考虑使用 InputEvent
作为键盘事件的替代(或补充)。
3.5.1. 接口 KeyboardEvent
在本规范中引入
The KeyboardEvent
interface provides specific contextual information
associated with keyboard devices. Each keyboard event references a key
using a value. Keyboard events are commonly directed at the element that
has the focus.
The KeyboardEvent
interface provides convenient attributes for some
common modifiers keys: ctrlKey,
shiftKey,
altKey,
metaKey.
These attributes are equivalent to using the
method getModifierState()
with Control,
Shift, Alt, or Meta
respectively.
To create an instance of the KeyboardEvent
interface, use the
KeyboardEvent
constructor, passing an optional
KeyboardEventInit
dictionary.
3.5.1.1. KeyboardEvent
[Exposed =Window ]interface :KeyboardEvent UIEvent {(constructor DOMString ,type optional KeyboardEventInit = {}); // KeyLocationCodeeventInitDict 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- 激活的按键来源于左侧位置(当该按键可能有多个位置时)。
DOM_KEY_LOCATION_RIGHT- 激活的按键来自右侧位置(当该按键可能有多个位置时)。
DOM_KEY_LOCATION_NUMPAD-
激活来源于数字小键盘或对应于数字小键盘的虚拟键(当该按键可能有多个位置时)。注意,
NumLock键应始终编码为location的值为DOM_KEY_LOCATION_STANDARD。 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_LEFT或DOM_KEY_LOCATION_RIGHT之一。该属性的未初始化值 必须为
0。 ctrlKey, 类型为 boolean,只读-
如果
Control(控制)键处于激活状态,则为true。该属性的未初始化值 必须为
false。 shiftKey, 类型为 boolean,只读-
如果 Shift(
Shift)键修饰符处于激活状态,则为true。该属性的未初始化值 必须为
false。 altKey, 类型为 boolean,只读-
如果
Alt(替代)(或"Option")键修饰符处于激活状态,则为true。该属性的未初始化值 必须为
false。 metaKey, 类型为 boolean,只读-
如果 Meta(
Meta)键修饰符处于激活状态,则为true。在 Macintosh 系统上,
"Command"("⌘")键修饰符使用此键修饰符表示。该属性的未初始化值 必须为
false。 repeat, 类型为 boolean,只读-
如果按键被持续按下则为
true。按住按键必须会按系统配置以一定速率重复触发keydown、beforeinput、input(按此顺序)。对于具有长按行为(long-key-press)的移动设备,首个具有repeat属性值为true的键事件必须作为长按的指示。开始重复的按下时间长度取决于配置。该属性的未初始化值 必须为
false。 isComposing, 类型为 boolean,只读-
如果键事件发生在合成会话期间,即在对应的
compositionstart事件之后且在对应的compositionend事件之前,则该值为true。该属性的未初始化值 必须为
false。 getModifierState(keyArg)-
使用键值查询修饰键的状态。
如果是修饰键且该修饰符被激活,则返回
true,否则返回false。- DOMString keyArg
-
一个修饰键值。有效的修饰键定义在
Modifier Keys 表(见 [UIEvents-Key])。
如果应用希望区分左右修饰键,可以使用键盘事件和
location推断该信息。
3.5.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] 中定义的 code 值之一。 location, 类型为 unsigned long,默认为0-
用于将 KeyboardEvent 对象的
location属性初始化为以下位置数值常量之一:-
DOM_KEY_LOCATION_STANDARD(数值 0) -
DOM_KEY_LOCATION_LEFT(数值 1) -
DOM_KEY_LOCATION_RIGHT(数值 2) -
DOM_KEY_LOCATION_NUMPAD(数值 3)
-
repeat, 类型为 boolean,默认为false-
用于初始化 KeyboardEvent 对象的
repeat属性。如果当前 KeyboardEvent 被视为由于按住某个按键导致的一系列重复事件的一部分,则应设置为true,否则为false。 isComposing, 类型为 boolean,默认为false-
用于初始化 KeyboardEvent 对象的
isComposing属性。如果所构造的事件发生在合成序列中,则应设置为true,否则为false。
keyCode、charCode 和 which。其中
keyCode 指示与计算机键盘上某个按键相关的数值,而 charCode 指示与该按键关联的字符的 ASCII 值(这可能与 keyCode 值相同),并且仅适用于产生字符值的按键。
实际上,keyCode 和 charCode 在不同平台间以及同一实现的不同操作系统或本地化设置上表现不一致。本规范不定义
keyCode 或 charCode 的取值,也不定义 charCode 的行为。在符合规范的 UI Events
实现中,内容作者可以改用 key
和 code。
更多信息请参见关于 旧有键属性 的说明性附录。
为了与现有内容兼容,诸如屏幕键盘等虚拟键盘预计会产生常规范围的键盘事件,即便它们不具备物理按键。
在某些实现或系统配置中,某些键事件或其值可能会被所使用的 IME 抑制。
3.5.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.5.3. 事件修饰符初始化器
The MouseEvent
和 KeyboardEvent
接口共享一组键盘修饰符属性,并支持检索额外修饰符状态的机制。下列字典允许作者初始化 MouseEvent
和
KeyboardEvent
接口的键盘修饰符属性,以及通过 getModifierState()
查询的额外修饰符状态。使用该字典构造鼠标事件的步骤在
[pointerevents4]
规范中定义。
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属性初始化为true(用于MouseEvent或KeyboardEvent对象),如果应将Control键修饰符视为已激活;否则为false。当为
true时,实现还必须初始化事件对象的键修饰符状态,以便在使用参数Control调用getModifierState()或getModifierState()时必须返回true。 shiftKey, 类型为 布尔值,默认值为false-
将
shiftKey属性初始化为true(用于MouseEvent或KeyboardEvent对象),如果应将Shift键修饰符视为已激活;否则为false。当为
true时,实现还必须初始化事件对象的键修饰符状态,以便在使用参数Shift调用getModifierState()或getModifierState()时必须返回true。 altKey, 类型为 boolean,默认值为false-
将
altKey属性初始化为true(用于MouseEvent或KeyboardEvent对象),如果应将Alt(或Option)键修饰符视为已激活;否则为false。当为
true时,实现还必须初始化事件对象的键修饰符状态,以便在使用参数Alt调用getModifierState()或getModifierState()时必须返回true。 metaKey, 类型为 boolean,默认值为false-
将
metaKey属性初始化为true(用于MouseEvent或KeyboardEvent对象),如果应将Meta键修饰符视为已激活;否则为false。当为
true时,实现还必须初始化事件对象的键修饰符状态,以便在使用参数Meta调用getModifierState()或getModifierState()时必须返回true。 modifierAltGraph, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
AltGraph调用getModifierState()或getModifierState()时必须返回true。 modifierCapsLock, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
CapsLock调用getModifierState()或getModifierState()时必须返回true。 modifierFn, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
Fn调用getModifierState()或getModifierState()时必须返回true。 modifierFnLock, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
FnLock调用getModifierState()或getModifierState()时必须返回true。 modifierHyper, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
Hyper调用getModifierState()或getModifierState()时必须返回true。 modifierNumLock, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
NumLock调用getModifierState()或getModifierState()时必须返回true。 modifierScrollLock, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
ScrollLock调用getModifierState()或getModifierState()时必须返回true。 modifierSuper, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
Super调用getModifierState()或getModifierState()时必须返回true。 modifierSymbol, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
Symbol调用getModifierState()或getModifierState()时必须返回true。 modifierSymbolLock, 类型为 boolean,默认值为false-
初始化事件对象的键修饰符状态,以便在使用参数
SymbolLock调用getModifierState()或getModifierState()时必须返回true。
3.5.4. KeyboardEvent 算法
3.5.4.1. KeyboardEvent 的全局状态
3.5.4.1.1. 用户代理级别的状态
用户代理必须维护以下在整个用户代理中共享的值。
A 键修饰符状态(初始为空),用于跟踪系统中每个修饰键的当前状态。
3.5.5. 键盘事件顺序
本规范定义的键盘事件对于任意给定键,其相互之间发生的顺序如下:
| 事件类型 | 说明 | |
|---|---|---|
| 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 元素(如果可用),否则为根元素 root element。
事件目标可能在不同的键事件之间发生变化。例如,keydown 事件(针对 Tab 键)很可能与同一次按键的 keyup 事件具有不同的事件目标。
3.5.6. 键盘事件类型
3.5.6.1. keydown
| 类型 | keydown
|
|---|---|
| 接口 | KeyboardEvent
|
| 同步 / 异步 | 同步 |
| 是否冒泡 | 是 |
| 受信任目标 | Element
|
| 可取消 | 是 |
| 可组成 | 是 |
| 默认动作 | 视情况而定:beforeinput 和 input 事件;启动 文本组合系统;blur 与 focus 事件;keypress
事件(如果支持);激活行为;其他事件
|
| 上下文 (受信任事件) |
|
用户代理(user
agent)必须在按键按下时派发此事件。keydown 事件类型依赖于设备,且取决于输入设备的能力以及它们在操作系统中的映射方式。此事件类型必须在键映射之后生成。此事件类型必须在与同一按键相关的beforeinput、input 和 keyup 事件之前派发。
keydown 事件的默认动作取决于按键:
-
如果按键与字符相关联,则默认动作必须是先派发一个
beforeinput事件,随后派发一个input事件。如果按键与多个字符相关联(例如宏或某些死键序列),则默认动作必须为每个字符派发一组beforeinput/input事件。 -
如果按键与 文本组合系统 相关联,则默认动作必须是启动该系统
-
如果按键是
Tab键,则默认动作必须是将文档焦点从当前获得焦点的元素(如果有)切换到新的获得焦点元素,如 焦点事件类型 中所述 -
如果按键是
Enter或(空格)键,且当前焦点位于一个会改变状态的元素上,则默认动作必须是派发一个click事件;如果用户代理支持该事件类型,还必须派发一个DOMActivate事件。
如果该事件被取消,则不得派发相关的事件类型,也不得执行相关的动作。
keydown 和 keyup
事件传统上与检测任意按键相关,而不仅仅是那些产生字符值的按键。
3.5.6.2. keyup
| 类型 | keyup
|
|---|---|
| 接口 | KeyboardEvent
|
| 同步 / 异步 | 同步 |
| 是否冒泡 | 是 |
| 受信任目标 | Element
|
| 可取消 | 是 |
| 可组成 | 是 |
| 默认动作 | 无 |
| 上下文 (受信任事件) |
|
用户代理(user
agent)必须在按键释放时派发此事件。keyup 事件类型依赖于设备,且取决于输入设备的能力以及它们在操作系统中的映射方式。此事件类型必须在键映射之后生成。此事件类型必须在与同一按键相关的 keydown、beforeinput 和
input 事件之后派发。
3.6. 合成事件
合成事件提供了一种不同于键盘事件的辅助或替代方式来输入文本,以便使用那些在键盘上可能不常见的字符。例如,合成事件可用于为字符添加重音(尽管标准美式键盘上没有这些字符)、从基本成分或类别构建许多亚洲语言的表意文字、在移动设备键盘上通过组合按键选择词选项,或使用语音识别处理器将语音命令转换为文本。有关合成事件与键盘事件结合使用的示例,请参阅 § 4 Keyboard events and key values。
概念上,合成会话由一个 compositionstart 事件、一个或多个 compositionupdate 事件,以及一个
compositionend 事件组成,在该事件链的每个“阶段”期间,data
属性的值会在整个会话中持续存在。
注意:
在合成会话处于活动状态时,如果键盘是与合成会话一起使用的输入设备,则键盘事件可以被派发到 DOM。请参阅 compositionstart 事件详情和 IME
部分 以了解相关的事件顺序。
并非所有的 IME 系统或设备都会向 DOM 暴露必要的数据,因此活动的合成字符串(“阅读窗口”或“候选选择菜单选项”)可能无法通过此接口获得,在这种情况下,选择可以用 空字符串 表示。
3.6.1. CompositionEvent 接口
在本规范中引入
The CompositionEvent
接口提供与合成事件相关的特定上下文信息。
要创建 CompositionEvent
接口的实例,
使用 CompositionEvent
构造函数,并传入可选的 CompositionEventInit
字典。
3.6.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.6.1.2. CompositionEventInit
dictionary :CompositionEventInit UIEventInit {DOMString data = ""; };
data, 类型为 DOMString,默认值为""-
初始化 CompositionEvent 对象的
data属性为 由 IME 合成生成的字符。
3.6.2. 合成事件顺序
本规范中定义的合成事件必须按下列顺序相互发生:
| 事件类型 | 说明 | |
|---|---|---|
| 1 | compositionstart
| |
| 2 | compositionupdate
| 多个事件 |
| 3 | compositionend
|
3.6.3. 手写识别系统
下面的示例描述了在使用手写识别系统(例如在手写板上)合成文本段落 text
时可能发生的事件序列,使用合成事件进行建模。
| 事件类型 | CompositionEventdata
| 说明 | |
|---|---|---|---|
| 1 | compositionstart
| ""
| |
| 用户在板面上书写单词 | |||
| 2 | compositionupdate
| "test"
| |
| 用户拒绝第一个词匹配建议,选择了不同的匹配 | |||
| 3 | compositionupdate
| "text"
| |
| 4 | compositionend
| "text"
|
3.6.4. 取消合成事件
如果一个 keydown 事件被取消,则任何因该
keydown 而可能触发的合成事件 不应
被派发:
| 事件类型 | 说明 | |
|---|---|---|
| 1 | keydown
| 默认 动作
被阻止,例如通过调用 preventDefault()。
|
| 不派发任何合成事件 | ||
| 2 | keyup
|
如果初始的 compositionstart 事件被取消,则文本合成会话 应 终止。无论合成会话是否被终止,compositionend 事件 必须 被发送。
| 事件类型 | 说明 | |
|---|---|---|
| 1 | keydown
| |
| 2 | compositionstart
| 默认 动作
被阻止,例如通过调用 preventDefault()。
|
| 不派发任何合成事件 | ||
| 3 | compositionend
| |
| 4 | keyup
|
3.6.5. 合成期间的键事件
在合成会话期间,仍然 必须 发送 keydown
和 keyup 事件,并且这些事件的
isComposing
属性 必须 设置为 true。
| 事件类型 | KeyboardEventisComposing
| 说明 | |
|---|---|---|---|
| 1 | keydown
| false | 这是启动合成的键事件。 |
| 2 | compositionstart
| ||
| 3 | compositionupdate
| ||
| 4 | keyup
| true | |
| ... | 在合成会话期间发送的任何键事件 必须 将 isComposing 设置为 true。
| ||
| 5 | keydown
| true | 这是退出合成的键事件。 |
| 6 | compositionend
| ||
| 7 | keyup
| false |
3.6.6. 合成期间的输入事件
在合成会话期间,必须在发送 compositionupdate 之前发送 beforeinput,但在发送 input 之前。
| 事件类型 | 说明 | |
|---|---|---|
| 1 | beforeinput
| |
| 2 | compositionupdate
| |
| 此时发生任何 DOM 更新。 | ||
| 3 | input
|
大多数 IME 不支持在合成会话期间取消更新。
当合成过程中 DOM 被更新时,beforeinput
与 input 事件会与
compositionupdate 事件一并发送。由于在 compositionend 事件发生时没有与之相关的 DOM 更新,因此在该时刻不应发送 beforeinput 和
input 事件。
| 事件类型 | 说明 | |
|---|---|---|
| 1 | beforeinput
| 取消此事件将阻止 DOM 更新以及随后的 input 事件。
|
| 2 | compositionupdate
| |
| 此时发生任何 DOM 更新。 | ||
| 3 | input
| 仅在 DOM 被更新时发送。 |
| 4 | compositionend
|
3.6.7. 合成事件类型
3.6.7.1. compositionstart
| Type | compositionstart
|
|---|---|
| Interface | CompositionEvent
|
| Sync / Async | Sync |
| Bubbles | Yes |
| Trusted Targets | Element
|
| Cancelable | Yes |
| Composed | Yes |
| Default action | 当启用 文本合成系统 时启动一个新的合成会话 |
| Context (trusted events) |
当启用 文本合成系统 并且新的合成会话即将开始(或已开始,取决于该 文本合成系统)以准备合成一段文本时,用户代理(user
agent) 必须 派发此事件。该事件类型依赖于设备,并且可能依赖于文本转换系统的能力及其在操作系统中的映射方式。当使用键盘为输入法编辑器提供输入时,此事件类型在 keydown
事件之后生成,但语音或手写识别系统可能在没有键盘事件的情况下发送该事件类型。一些实现可能会在 data 属性中填充当前文档中选中的文本(用于编辑和替换)。否则,data 属性的值 必须 为 空字符串。
此事件 必须 在 文本合成系统 开始新的合成会话之前立即派发,并且在由于合成过程而修改 DOM 之前派发。该事件的默认动作是由 文本合成系统 开始一个新的合成会话。如果此事件被取消,则 文本合成系统 应 丢弃 当前合成会话。
取消 compositionstart 事件类型 与 取消 文本合成系统 本身(例如,按下取消按钮或关闭
IME 窗口)是不同的概念。
某些 IME 不支持取消正在进行的合成会话(例如 GTK 目前没有这样的 API)。在这些情况下,调用 preventDefault()
将不会停止该事件的默认动作。
3.6.7.2. compositionupdate
| Type | compositionupdate
|
|---|---|
| Interface | CompositionEvent
|
| Sync / Async | Sync |
| Bubbles | Yes |
| Trusted Targets | Element
|
| Cancelable | No |
| Composed | Yes |
| Default action | None |
| Context (trusted events) |
当 文本合成系统 在合成会话期间将其活动文本段更新为一个新字符并反映在 data
字符串中时,用户代理(user
agent) 应 派发 此 事件。
在将正在进行的合成与输入控件保持同步的 文本合成系统 中,必须在控件更新之前派发 compositionupdate 事件。
某些 文本合成系统 可能不会将此信息暴露给 DOM,在这种情况下在合成过程中不会触发该事件。
如果合成会话被取消,则此事件将在 compositionend 事件之前立即触发,且 data
属性将被设置为 空字符串。
3.6.7.3. compositionend
| Type | compositionend
|
|---|---|
| Interface | CompositionEvent
|
| Sync / Async | Sync |
| Bubbles | Yes |
| Trusted Targets | Element
|
| Cancelable | No |
| Composed | Yes |
| Default action | None |
| Context (trusted events) |
当 文本合成系统 完成或取消当前合成会话时,用户代理(user
agent) 必须 派发 此 事件,并且 compositionend 事件 必须 在 控件 更新 之后 被派发。
此事件在 文本合成系统 完成合成会话后(例如 IME 被关闭、最小化、失去焦点或以其他方式被解散,并且焦点切换回用户代理)立即派发。
4. 键盘事件与按键值
本章节包含有关键盘事件的必要信息:
-
键盘布局、映射和按键值的说明。
-
按键之间的关系,如 死键 或修饰键。
-
键盘事件与其默认行为之间的关系。
-
key值集合及如何扩展该集合的指导。
本章节使用了塞尔维亚语和日文汉字字符,在规范的 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.
key
与 code
的关系
keykey属性适用于关注按键实际意义(考虑当前键盘布局和输入法,死键有独特key值)的人群。典型用例:检测修饰键或裸修饰键(如响应快捷键)。codecode属性适用于关注用户实际按下哪个物理按键的人群,不受布局影响。典型用例:检测 WASD 键(如游戏的移动控制)或拦截所有按键(如远程桌面客户端将所有按键发送到远程主机)。
4.2.3. code 示例
| 键盘布局 | KeyboardEventkey
| KeyboardEventcode
| 说明 |
|---|---|---|---|
| US | "Alt"
| "AltLeft"
| DOM_KEY_LOCATION_LEFT
|
| French | "Alt"
| "AltLeft"
| DOM_KEY_LOCATION_LEFT
|
| US | "Alt"
| "AltRight"
| DOM_KEY_LOCATION_RIGHT
|
| French | "AltGraph"
| "AltRight"
| DOM_KEY_LOCATION_RIGHT
|
在此示例中,检查 key
属性允许匹配 Alt 而无需关心按下的是左侧还是右侧的 Alt 键。检查 code
属性则允许匹配右侧 Alt 键("AltRight"),而不必担心当前使用的是哪种布局。
注意,在法语示例中,尽管每种键只存在一个,Alt 和 AltGraph
键仍然保留它们的左/右位置。
| 键盘布局 | KeyboardEventkey
| KeyboardEventcode
| 说明 |
|---|---|---|---|
| US | "'
| "Quote"
| |
| Japanese | ":"
| "Quote"
| |
| US Intl | "Dead"
| "Quote"
|
"2" 键(按下或未按下 Shift)在各种键盘布局上的行为。
| 键盘布局 | KeyboardEventkey
| KeyboardEventcode
| 说明 |
|---|---|---|---|
| US | "2"
| "Digit2"
| |
| US | "@"
| "Digit2"
| shiftKey
|
| UK | "2"
| "Digit2"
| |
| UK | """
| "Digit2"
| shiftKey
|
| French | "é"
| "Digit2"
| |
| French | "2"
| "Digit2"
| shiftKey
|
无论当前区域设置或修饰键状态如何,在美式键盘上按下标有 "2" 的物理键,"Digit2"
总是出现在 code
属性中。
Shift 和 2
比较下面两个按键事件序列中的属性值。它们都在美式键盘上产生 "@" 字符,但释放键的顺序不同。在第一个序列中,顺序是:Shift(按下)、2(按下)、2(抬起)、Shift(抬起)。
| 事件类型 | KeyboardEventkey
| KeyboardEventcode
| 说明 | |
|---|---|---|---|---|
| 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(抬起)。
| 事件类型 | KeyboardEventkey
| KeyboardEventcode
| 说明 | |
|---|---|---|---|---|
| 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),或其它相关用途。符合规范的宿主语言应允许内容作者使用按键值的两个等价字符串之一:字符值或按键值。
虽然实现会根据平台或键盘布局独立使用最相关的按键值,但内容作者不能假设键盘设备都能生成这些值。在用作快捷键组合时,可以考虑使用数字和功能键(
([DWW95]),因为大多数键盘布局都提供这些键。
F4、F5等)而不是字母
按键值不表示物理键盘上的具体按键,也不反映按键上印刷的字符。按键值表示事件的当前值,会考虑所有活动按键和输入模式(包括 shift 模式)的当前状态,由操作系统的键盘映射反映并报告给实现。换言之,QWERTY 键盘上标记为 O 的键在未按 shift 时 "o",按下 shift 时为 "O"。由于用户可将键盘映射为任意自定义配置,内容作者不应假设按键的 shift/unshift 状态与字符的大小写存在对应关系,而应始终使用 key
属性值。例如,[UIEvents-Code] 中的 Standard "102" 键盘布局展示了一种可能的按键映射,还有许多其它标准或个性化布局。
为简化死键支持,当操作系统键盘映射处于死键状态时,死键序列的当前状态不会通过 key
属性报告,而会报告按键值 "Dead"。实现会生成组合事件,其中死键序列的中间状态通过 data
属性报告。如前例,QWERTY 键盘上的 O 键在添加变音符时,未按 shift 时 "ö",按下
shift 时 "Ö"。
还要注意,按键事件状态与按键值之间不是一一对应关系。某个按键值可能关联多个按键。例如,许多标准键盘有多个 Shift 键值(通常通过 location
的 DOM_KEY_LOCATION_LEFT
和 DOM_KEY_LOCATION_RIGHT
区分),或多个 8 键值(通过 location
的 DOM_KEY_LOCATION_STANDARD
和 DOM_KEY_LOCATION_NUMPAD
区分),用户自定义布局可在多个按键状态下重复任何按键值(注意 location
主要用于标准键盘布局,不能总能区分)。
最后,任意字符表示的意义取决于具体上下文且较为复杂。例如,在某些上下文下,星号符号("*")表示脚注或强调(如包围文本段落),但在某些文档或程序中等价于乘法运算符,而在其他文档或程序中该功能由乘号符号("×",Unicode 编码 U+00D7)或小写字母 "x"
实现(因多数键盘无专用乘号键且符号形似)。因此字符表示的语义和功能不属于本规范范围。
4.3.1. 修饰键
键盘输入使用修饰键来改变按键的正常行为。像其他按键一样,修饰键会产生 keydown 和
keyup
事件,如下面的示例所示。某些修饰键在按下或保持按下时被激活,例如 Alt、Control、Shift、AltGraph
或
Meta。其他修饰键则根据其状态被激活,例如 CapsLock、NumLock 或 ScrollLock。状态的变化发生在修饰键被按下时。KeyboardEvent
接口为一些常见的修饰键提供了方便的属性:ctrlKey、
shiftKey、
altKey、
metaKey。
某些操作系统用 Alt 和 Control 修饰键的组合作为 AltGraph 修饰键的模拟。建议实现使用 AltGraph 修饰键。
U+0051)时可能发生的一系列事件:
| 事件类型 | KeyboardEventkey
| 修饰键 | 说明 | |
|---|---|---|---|---|
| 1 | keydown
| "Shift"
| shiftKey
| |
| 2 | keydown
| "Q"
| shiftKey
| 拉丁大写字母 Q |
| 3 | beforeinput
| |||
| 4 | input
| |||
| 5 | keyup
| "Q"
| shiftKey
| |
| 6 | keyup
| "Shift"
|
Shift 键在 Q 键之前被释放。Q 键的键值将在 keyup 事件中恢复为未加 Shift 的值:
| 事件类型 | KeyboardEventkey
| 修饰键 | 说明 | |
|---|---|---|---|---|
| 1 | keydown
| "Shift"
| shiftKey
| |
| 2 | keydown
| "Q"
| shiftKey
| 拉丁大写字母 Q |
| 3 | beforeinput
| |||
| 4 | input
| |||
| 5 | keyup
| "Shift"
| ||
| 6 | keyup
| "q"
| 拉丁小写字母 q |
| 事件类型 | KeyboardEventkey
| 修饰键 | 说明 | |
|---|---|---|---|---|
| 1 | keydown
| "Control"
| ctrlKey
| |
| 2 | keydown
| "v"
| ctrlKey
| 拉丁小写字母 v |
不会生成 beforeinput 或 input
事件。
| ||||
| 3 | keyup
| "v"
| ctrlKey
| 拉丁小写字母 v |
| 4 | keyup
| "Control"
|
Shift 和 Control 时的事件序列:
| 事件类型 | KeyboardEventkey
| 修饰键 | 说明 | |
|---|---|---|---|---|
| 1 | keydown
| "Control"
| ctrlKey
| |
| 2 | keydown
| "Shift"
| ctrlKey,
shiftKey
| |
| 3 | keydown
| "V"
| ctrlKey,
shiftKey
| 拉丁大写字母 V |
不会生成 beforeinput 或 input
事件。
| ||||
| 4 | keyup
| "V"
| ctrlKey,
shiftKey
| 拉丁大写字母 V |
| 5 | keyup
| "Shift"
| ctrlKey
| |
| 6 | keyup
| "Control"
|
| 事件类型 | KeyboardEventkey
| 修饰键 | 说明 | |
|---|---|---|---|---|
| 1 | keydown
| "Control"
| ctrlKey
| |
| 2 | keydown
| "ر"
| ctrlKey
| 阿拉伯字母 Reh |
不会生成 beforeinput 或 input
事件。
| ||||
| 3 | keyup
| "ر"
| ctrlKey
| 阿拉伯字母 Reh |
| 4 | keyup
| "Control"
|
keydown 和 keyup 事件中的值会根据按下按键时所用的键盘布局而变化。这意味着美式布局下的 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 的首选。
| 事件类型 | KeyboardEventkey
| KeyboardEventisComposing
| CompositionEventdata
| 说明 | |
|---|---|---|---|---|---|
| 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),因为传递给用户代理的值已经被死键操作修改。
当用户在按下 死键 之后输入一个不被支持的基字符(即对于当前活动的变音符不可用的基字符)时,该过程可能会被中止:
| 事件类型 | KeyboardEventkey
| KeyboardEventisComposing
| CompositionEventdata
| 说明 | |
|---|---|---|---|---|---|
| 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
接口获取。此外,不同的输入法系统和设备功能不同,激活这些功能的按键也不同,Convert 和 Accept
键也可能由其他可用按键表示。键盘事件对应于键盘布局映射之后由输入设备生成的事件。
在部分实现或系统配置下,部分按键事件及其值可能会被正在使用的输入法抑制。
下例展示了通过日语输入法生成 Unicode 字符 "市"(汉字,CJK统一表意文字之一)的一组可能按键序列。假定输入法已激活并处于日文罗马字输入模式。Convert 和 Accept
键可能被其他按键替换,具体取决于输入设备和输入法配置,例如分别可以是 U+0020(空格键)和 Enter。
"詩"(诗)和 "市"(市)为同音字,都读作
し(shi/si),用户需用 Convert 键选择正确选项。
| 事件类型 | KeyboardEventkey
| KeyboardEventisComposing
| CompositionEventdata
| 备注 | |
|---|---|---|---|---|---|
| 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键)。
| 事件类型 | KeyboardEventkey
| KeyboardEventisComposing
| CompositionEventdata
| 备注 | |
|---|---|---|---|---|---|
| 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 イベントには影響しませんが、対応する beforeinput や
input(および keypress
がサポートされている場合)イベントの生成を防止する必要があります。次の例は、USキーボードでUSマッピングを使って Unicode文字Q(ラテン大文字Q)を生成する一連のキー操作を示しています。
| イベントタイプ | KeyboardEventkey
| InputEventdata
| 修飾キー | 注記 | |
|---|---|---|---|---|---|
| 1 | keydown
| "Shift"
| shiftKey
| ||
| 2 | keydown
| "Q"
| shiftKey
| デフォルト動作が阻止される(例:preventDefault()
を呼び出す)
| |
beforeinput や input
(および keypressがサポートされていれば)イベントは生成されません
| |||||
| 3 | keyup
| "Q"
| shiftKey
| ||
| 4 | keyup
| "Shift"
|
キーが修飾キーの場合でも、キーストロークは修飾キー状態の計算に必ず考慮されます。次の例もUSマッピングで ラテン大文字Q を生成する一連の操作です。
| イベントタイプ | KeyboardEventkey
| InputEventdata
| 修飾キー | 注記 | |
|---|---|---|---|---|---|
| 1 | keydown
| "Shift"
| shiftKey
| デフォルト動作が阻止される(例:preventDefault()
を呼び出す)
| |
| 2 | keydown
| "Q"
| shiftKey
| ||
| 3 | beforeinput
| "Q"
| |||
| 4 | input
| ||||
| 5 | keyup
| "Q"
| shiftKey
| ||
| 6 | keyup
| "Shift"
|
キーが複数キー操作列の一部(デッドキーや IME操作系列など)なら、デフォルト動作が keydown
イベントでキャンセルされた場合のみ、そのキーストロークは無視する(計算から除外する)必要があります。keyup イベントで デッドキーをキャンセルしても、beforeinput や input イベントには影響しません。下記例はフランス配列のキーボードでフランスマッピング、修飾キーなしでデッドキー
"Dead"(U+0302 サーカムフレックスアクセントキー)と "e"(U+0065、ラテン小文字eキー)を使用する操作例です:
| イベントタイプ | KeyboardEventkey
| InputEventdata
| 注記 | |
|---|---|---|---|---|
| 1 | keydown
| "Dead"
| デフォルト動作が阻止される(例:preventDefault()
を呼び出す)
| |
| 2 | keyup
| "Dead"
| ||
| 3 | keydown
| "e"
| ||
| 4 | beforeinput
| "e"
| ||
| 5 | input
| |||
| 6 | keyup
| "e"
|
5. 外部算法
本节包含本规范所需但更适合由其他规范托管的算法。
本节的目的是作为这些定义的临时存放处,最终应将它们移入更合适的位置,以便删除整个本节。
5.1. 核心 DOM 算法
下列算法应当被移到……某个地方。
5.2. PointerLock 算法
下列算法应当被移入 [PointerLock] 规范。
5.2.1. PointerLock 的全局状态
5.2.1.1. 窗口级状态
用户代理必须维护以下在 Window 级别共享的值。
A 最后一次鼠标移动 值(初始为未定义),用于记录最后一个 mousemove 事件的位置。
5.2.2. 为 MouseEvent 初始化 PointerLock 属性
- 输入
-
event,一个
MouseEvent - 输出
-
无
5.2.3. 为 mousemove 设置 PointerLock 属性
- 输入
-
event,一个
MouseEvent - 输出
-
无
6. 遗留事件初始化器
本节为规范性。 以下特性已被废弃,仅应由需要与遗留软件兼容的用户代理实现。
本规范的早期版本在接口上包含一个初始化方法(例如 initMouseEvent),该方法需要很长的参数列表,而在多数情况下并不能完全初始化事件对象的所有属性。正因为如此,从基本
Event
接口派生的事件接口要求必须显式地调用每个派生接口的初始化器,才能完全初始化一个事件。
由于本标准开发时间较长,某些实现可能已经依赖于这些(现在已弃用的)初始化方法。为完整性起见,这些遗留事件初始化器在本附录中予以说明。
6.1. 遗留事件初始化器接口
本节为信息性内容
本节记录了在本规范早期版本中引入的遗留初始化方法。
6.1.1. UIEvent 接口的初始化器
partial interface UIEvent { // Deprecated in this specificationundefined initUIEvent (DOMString ,typeArg optional boolean =bubblesArg false ,optional boolean =cancelableArg false ,optional Window ?=viewArg null ,optional long = 0); };detailArg
initUIEvent(typeArg)-
初始化一个
UIEvent对象的属性。 该方法的行为与initEvent()相同。initUIEvent方法已被弃用,但为与已广泛部署的实现向后兼容而保留支持。- DOMString typeArg
-
有关此参数的描述,请参阅
initEvent()方法。 - boolean bubblesArg
-
有关此参数的描述,请参阅
initEvent()方法。 - boolean cancelableArg
-
有关此参数的描述,请参阅
initEvent()方法。 - Window? viewArg
-
指定
view。 该值可以为null。 - long detailArg
-
指定
detail。
6.1.2. KeyboardEvent 接口的初始化器
此传统 KeyboardEvent 初始化函数的参数列表不包含 detailArg(其他初始化函数中会有),
并新增了 locale 参数;为了与现有实现兼容,
有必要保留该不一致性。
partial interface KeyboardEvent { // Originally introduced (and deprecated) in this specificationundefined initKeyboardEvent (DOMString ,typeArg optional boolean =bubblesArg false ,optional boolean =cancelableArg false ,optional Window ?=viewArg null ,optional DOMString = "",keyArg optional unsigned long = 0,locationArg 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.3. CompositionEvent 接口的初始化器
此遗留 CompositionEvent 初始化器的参数列表不包含其他初始化器中存在的 detailArg,并且新增了 locale
参数;为与现有实现兼容,有必要保留该不一致性。
partial interface CompositionEvent { // Originally introduced (and deprecated) in this specificationundefined 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
属性,而不要使用 charCode
和 keyCode
属性。
不过,为了记录这些功能的当前状态及其与规范性事件和属性的关系,本节提供了信息性描述。对于支持这些属性和事件的实现,建议使用本节中给出的定义。
7.1. 遗留 UIEvent
补充接口
本节为非规范性
用户代理历来包含一个 which
属性,以便 KeyboardEvent
和 MouseEvent
能记录补充的事件信息。
本规范的先前版本将单独的 which
属性直接定义在 KeyboardEvent
和 MouseEvent
上,而不是在 UIEvent 上定义共享的
which
属性。
7.1.1. 接口 UIEvent(补充)
该部分的 UIEvent
接口是对 UIEvent
接口的一个信息性扩展,增加了 which
属性。
partial interface UIEvent { // The following support legacy user agentsreadonly attribute unsigned long which ; };
which, 类型为 unsigned long,只读-
对于
MouseEvent, 该值等于存储在button中的值再加 1。 对于KeyboardEvent, 该值包含一个系统和实现相关的数字代码,表示与所按下键关联的未修改标识符。在大多数情况下,该值与keyCode相同。
7.1.2. 接口 UIEventInit(补充)
在 which
支持被包含在 UIEvent
中的浏览器中,应当向 UIEventInit
字典添加下列成员。
该部分的 UIEventInit
字典是对 UIEventInit
字典的信息性扩展,增加了用于初始化相应 UIEvent
属性的 which
成员。
partial dictionary UIEventInit {unsigned long which = 0; };
which, 类型为 unsigned long,默认值为0-
初始化
which属性的UIEvent。
7.2. 遗留 KeyboardEvent
补充接口
本节为非规范性
浏览器对键盘的支持历来依赖于三种临时性的属性:keyCode、
charCode
以及 UIEvent 的
which。
这三者均返回一个数值代码,用以表示所按键的某些方面:keyCode
是对键自身的一个索引。charCode
是字符键的 ASCII 值。which
在可用时表示字符值,否则表示键的索引。这些属性的值以及属性的可用性在不同平台、键盘语言和布局、用户代理、版本,甚至事件类型之间并不一致。
7.2.1. 接口 KeyboardEvent(补充)
该部分的 KeyboardEvent
接口是对 KeyboardEvent
接口的信息性扩展,增加了 charCode
和 keyCode
属性。
对于支持此扩展的实现,可以通过调用 createEvent()
方法来获取该部分的 KeyboardEvent
接口。
partial interface KeyboardEvent { // The following support legacy user agentsreadonly attribute unsigned long charCode ;readonly attribute unsigned long keyCode ; };
charCode, 类型为 unsigned long,只读-
charCode保存一个字符值,用于产生字符输入的keypress事件。该值为该字符的 Unicode 编码点(例如,对于可打印字符,等于event.key.charCodeAt(0))。对于keydown或keyup事件,charCode的值为0。 keyCode, 类型为 unsigned long,只读-
keyCode保存一个系统和实现相关的数字代码,表示与所按下键关联的未修改标识符。与key属性不同,本规范并未对可能的取值集合进行规范性定义。通常,keyCode的值应当表示 ASCII 的十进制码点 [RFC20][US-ASCII] 或 Windows 1252 [WIN1252] 中的十进制值,但也可能取自其他合适的字符集。无法识别键的实现使用键值0。关于如何确定
keyCode的值的更多细节,请参阅 § 7.3 Legacy key models。
7.2.2. 接口 KeyboardEventInit(补充)
在 keyCode
和 charCode
被包含在 KeyboardEvent
中的浏览器,应当向 KeyboardEventInit
字典添加下列成员。
该部分的 KeyboardEventInit
字典是对 KeyboardEventInit
字典的信息性扩展,增加了用于初始化相应 KeyboardEvent
属性的 charCode
和 keyCode
成员。
partial dictionary KeyboardEventInit { // The following support legacy user agentsunsigned long charCode = 0;unsigned long keyCode = 0; };
charCode, 类型为 unsigned long,默认值为0-
初始化
charCode属性的KeyboardEvent为事件的字符设置 Unicode 代码点值。 keyCode, 类型为 unsigned long,默认值为0-
初始化
keyCode属性的KeyboardEvent为所按下键关联的未修改标识符设置系统和实现相关的数字代码。
7.3. 传统键位模型
本节为非规范性内容
不同实现会为不同事件类型暴露这些属性的不同值。实现可以选择在keyCode
属性中同时暴露虚拟键码和字符码(混合模型),或者分别报告keyCode
和charCode
属性(分离模型)。
7.3.1.
如何确定keyCode用于keydown和keyup事件
keyCode
在keydown或keyup事件中计算规则如下:
-
从操作系统事件信息读取虚拟键码(如有)。
-
如果输入法正在处理键盘输入且事件为
keydown,则返回229。 -
如果输入按下时不带修饰键会输入数字字符(0-9),则返回该数字字符的ASCII码。
-
如果输入按下时不带修饰键会输入a-z范围的小写字符,则返回对应大写字符的ASCII码。
-
如果实现支持操作系统和平台的键码转换表,则查找该表,若指定了备用虚拟键值则返回。
-
如果该键的功能(由实现自定)与§ 7.3.3 固定虚拟键码表中的某一键对应,则返回表中键码。
-
返回操作系统的虚拟键码。
-
如果没有找到键码,则返回0。
7.3.2.
如何确定keyCode用于keypress
事件
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
| 是 | 是 | 各不相同:触发 文本合成系统; blur 和 focus 事件; DOMActivate 事件; 以及其他事件
|
textInput
| 同步 | 是 | Element
| TextEvent
| 是 | 是 | 见定义 |
8.1.
遗留 UIEvent
事件
8.1.1.
遗留 UIEvent
事件类型
8.1.1.1. DOMActivate
| 类型 | DOMActivate
|
|---|---|
| 接口 | UIEvent
|
| 同步 / 异步 | 同步 |
| 是否冒泡 | 是 |
| 受信任目标 | Element
|
| 可取消 | 是 |
| 是否组成 | 是 |
| 默认动作 | 无 |
| 上下文 (受信任事件) |
当按钮、链接或其他改变状态的元素被激活时,用户代理必须分发此事件。
DOMActivate
事件类型在本规范中作为参考和完整性而定义,但本规范弃用对此事件类型的使用,建议使用相关的
事件类型 click。其他规范可能会为向后兼容定义并保留它们自己的 DOMActivate 事件类型。
虽然 DOMActivate
和 click 并不完全等价,
已实现的 click 事件类型 的行为已经演变为涵盖 DOMActivate 事件设计时最关键的辅助功能方面,并且得到了更广泛的实现。建议内容作者使用
click 事件类型,而不是相关的 mousedown
或 mouseup 事件类型 以确保最大可访问性。
支持 DOMActivate 事件类型 的实现 应当
在与激活触发器相关联的 click 事件的默认动作中也分发一个 DOMActivate 事件。然而,此类实现对于给定的激活触发器的每次发生只应启动一次相关的激活行为。
DOMActivate
事件类型是 XForms [XFORMS11] 强制要求支持的,该类型旨在于
宿主语言中实现。在某些场景下,如果
XForms 插件或基于脚本的实现需要安装到本规范的原生实现中,但原生实现不支持
DOMActivate
事件类型,则 XForms 用户代理必须根据相关的 激活触发条件自行合成并派发 DOMActivate 事件。
因此,当一个遵循 UI Events 的 用户代理 分发一个 click 事件时,XForms 的用户代理必须确定是否合成一个与该 默认动作 相同相关属性的 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
事件类型在本规范中作为参考和完整性而定义,但本规范弃用对此事件类型的使用,建议使用相关的事件类型 focus 和 focusin。
8.2.1.2. DOMFocusOut
| 类型 | DOMFocusOut
|
|---|---|
| 接口 | FocusEvent
|
| 同步 / 异步 | 同步 |
| 是否冒泡 | 是 |
| 受信任目标 | Window, Element
|
| 可取消 | 否 |
| 是否组成 | 是 |
| 默认动作 | 无 |
| 上下文 (受信任事件) |
|
用户代理必须在事件目标失去焦点时分发此事件。焦点必须在此事件类型分发之前从该元素移除。此事件类型必须在事件类型 blur 之后分发。
DOMFocusOut
事件类型在本规范中作为参考和完整性而定义,但本规范弃用对此事件类型的使用,建议使用相关的事件类型 blur 和 focusout。
8.2.2. 遗留 FocusEvent 事件顺序
下面是在元素之间切换焦点时的典型事件序列,包括已弃用的 DOMFocusIn 和
DOMFocusOut
事件。所示顺序假定最初没有元素被聚焦。
| 事件类型 | 说明 | |
|---|---|---|
| 用户切换焦点 | ||
| 1 | focusin
| 在第一个目标元素接收焦点之前发送 |
| 2 | focus
| 在第一个目标元素接收焦点之后发送 |
| 3 | DOMFocusIn
| 如果支持 |
| 用户切换焦点 | ||
| 4 | focusout
| 在第一个目标元素失去焦点之前发送 |
| 5 | focusin
| 在第二个目标元素接收焦点之前发送 |
| 6 | blur
| 在第一个目标元素失去焦点之后发送 |
| 7 | DOMFocusOut
| 如果支持 |
| 8 | focus
| 在第二个目标元素接收焦点之后发送 |
| 9 | DOMFocusIn
| 如果支持 |
8.3.
遗留 KeyboardEvent
事件
keypress 事件是捕获按键事件并在
DOM 更新为按键效果之前处理它们的传统方法。使用 keypress 事件的代码通常依赖于遗留的 charCode、
keyCode
和
which
属性。
注意,keypress
事件特定于按键事件,已被更通用的事件序列 beforeinput 和
input 事件取代。这些新的
input 事件不特定于键盘操作,可用于捕获无论原始来源为何的用户输入。
8.3.1. 遗留 KeyboardEvent
事件类型
8.3.1.1. keypress
| 类型 | keypress
|
|---|---|
| 接口 | KeyboardEvent
|
| 同步 / 异步 | 同步 |
| 是否冒泡 | 是 |
| 受信任目标 | Element
|
| 可取消 | 是 |
| 是否组成 | 是 |
| 默认动作 | 各不相同:
触发 文本合成系统;
blur 和 focus 事件;
DOMActivate 事件;
以及其他事件
|
| 上下文 (受信任事件) |
|
如果被 用户代理支持,则当按下某个键且该键通常产生字符值时,必须分发该事件。keypress 事件类型依赖于设备和操作系统中输入设备的映射,因此具有设备相关性。
此事件类型必须在键映射之后生成。使用输入法编辑器时不得触发此事件。
如果此事件被取消,则除了取消默认动作外,还应阻止input 事件的触发。
作者应在编辑上下文中使用 beforeinput 事件替代 keypress 事件。
keypress
事件传统上用于检测字符值(character
value)而非物理键,并且在某些配置中可能并非对所有键都可用。
keypress
事件类型在本规范中被定义作为参考和完整性,但本规范弃用对此事件类型的使用。在编辑上下文中,作者可以订阅 beforeinput 事件来代替。
8.3.2.
keypress 事件顺序
keypress
事件类型必须在与同一按键关联的 keydown
事件之后并在 keyup 事件之前分发。
keypress
事件类型必须在与同一按键关联的 beforeinput 事件之后并在 input 事件之前分发。
下例演示了对支持 keypress
事件的用户代理来说的按键事件序列:
| 事件类型 | KeyboardEventkey
| InputEventdata
| 说明 | |
|---|---|---|---|---|
| 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 = "undefined"); };data
参见 UI Events 算法中的 Text Event 部分,了解 TextEvent
接口和 textInput 事件的相关内容。
9. 扩展事件
本节为非规范性内容
9.1. 简介
本规范定义了若干接口和许多事件,但并不是为所有目的提供了完整的事件集合。为了让内容作者和实现者能够添加所需功能,且不产生冲突,本规范提供了两种机制来扩展这些接口和事件集:自定义事件和实现特定扩展。
9.2. 自定义事件
脚本作者可以希望根据功能组件来定义应用程序,并定义对应用架构有意义的事件类型。内容作者可以使用CustomEvent
接口
创建适合其抽象级别的自定义事件。
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 应用可监听error和load事件,从而判断本地系统可访问哪些网络计算机或哪些端口处于开放状态,为后续攻击做准备。
仅有 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 或标准文档中的类似定义。更多信息请参见定义中的链接。
- activation trigger
-
被定义为启动激活行为的事件。
- author
-
在本规范的上下文中,author、content author 或 script author 指撰写脚本或其他可执行内容并使用本规范中所定义的接口、事件和事件流的人。有关更多细节,请参阅符合性类别中的 § 1.2.3 内容作者与内容。
- body element
-
在 HTML 或 XHTML 的文档中,body 元素表示文档的内容。在格式良好的 HTML 文档中,body 元素是根元素的第一个子孙元素。
- character value
-
在键值的上下文中,字符值是表示一个或多个 Unicode 字符(例如一个字母或符号,或一组字母,每个字母都属于有效的Unicode 字符类别集合)的字符串。在本规范中,字符值以 Unicode 字符串表示(例如,
U+0020)或相同代码点的字形表示(例如," "),并以颜色编码来帮助区分这两种表示。在源代码中,一些键值(例如非图形字符)可以使用所用编程语言的字符转义语法来表示。
- dead key
-
死键是单独按下不会产生字符的键或键组合,但与另一个键组合或顺序输入时会产生被修饰的字符,例如带变音符号的字符(例如,
"ö"、"é"、"â")。 - default action
-
默认动作是一个可选的补充行为,实现在分发事件对象时必须与之配合执行。每个事件类型定义以及每个规范都会为该事件类型(如果有的话)定义默认动作。在某些情况下(例如当与激活触发器相关联时),一个事件实例可能具有多个默认动作。可以通过调用
preventDefault()方法来取消默认动作。 - delta
-
估计的滚动量(以像素、行或页为单位),这是用户代理响应支持
WheelEvent接口的物理输入设备(例如滚轮或触控板)的移动时将滚动或缩放页面的量。一个delta的值(例如deltaX、deltaY或deltaZ属性)应根据当前的deltaMode属性来解释。滚轮(或其他设备)物理移动与 delta 为正或负之间的关系取决于环境和设备。然而,如果用户代理将滚动作为默认动作,则delta 的符号由右手坐标系给出,其中正的 X、Y、Z 轴分别指向文档(document)的最右边缘、最下边缘和最远深度(远离用户)。 - deprecated
-
标记为弃用的功能包含在规范中以便参考旧实现或旧规范,但它们是可选且不鼓励使用的。只有那些已有或正在进行替代方案的功能才必须在本规范中被标记为弃用。尚未包含该功能的实现可出于与现有内容向后兼容的原因实现被弃用的功能,但内容作者在创建内容时不应使用被弃用的功能,除非没有其他方法能满足用例。引用本规范的其他规范不应使用被弃用的功能,而应指向该功能被弃用所替代的替代方案。本规范中标记为弃用的功能预期将在未来的规范中被移除。
- empty string
-
空字符串是长度为
0的DOMString值,即不包含任何字符(既不包含可打印字符也不包含控制字符)的字符串。 - event focus
-
事件焦点是文档内特定元素或其他事件目标上的一种特殊的接收和集中注意力状态。每个元素在获得焦点时有不同的行为,取决于其功能,例如为激活做准备(如按钮或超链接)、切换状态(如复选框)、接收文本输入(如文本表单字段)或复制已选文本。有关更多详细信息,请参阅 § 3.3.3 文档焦点与焦点上下文。
- event focus ring
-
事件焦点环是在一个事件焦点目标集合中的有序集合,位于一个文档内。宿主语言可以定义一种或多种确定目标顺序的方法,例如文档顺序、为每个焦点目标定义的数字索引、焦点目标之间的显式指针,或不同模型的混合。每个文档可以包含多个焦点环或条件性焦点环。通常,对于文档顺序或索引化的焦点环,焦点会从最后一个目标“环回”到第一个目标。
- event target
-
事件流中事件所针对的对象。事件目标是事件对象上
target属性的值。 - event type
-
事件类型是具有特定名称的事件对象,且定义了特定的触发条件、属性和其他特性,这些特性将其与其他事件类型区分开来。例如,
keydown事件类型具有不同于blur或load事件类型的特性。事件类型在事件对象上以type属性公开。也可宽泛地称为“事件”,例如keydown事件。 - host language
-
任何将另一个语言或 API 规范的功能集成进来,同时规范性地引用原始规范而不是重新定义这些功能,并且仅以原始规范所定义的方式扩展这些功能的语言。原始规范通常旨在在一个或多个宿主语言的上下文中实现,而不是作为独立语言实现。例如,XHTML、HTML 和 SVG 是 UI Events 的宿主语言,它们集成并扩展了本规范中定义的对象和模型。
- IME
- input method editor
-
输入法编辑器(IME),也称为前端处理器,是执行按键与表意文字或其他字符之间转换的应用程序,通常通过用户引导的字典查找实现,常用于东亚语言(例如中文、日语、韩语)。IME 也可用于基于字典的单词补全,例如在移动设备上。有关 IME 在本规范中的处理,请参见 § 4.3.3 输入法编辑器。另见 文本合成系统。
- key mapping
-
键映射是将键值分配给特定键的过程,其结果由多个因素的组合决定,包括操作系统和键盘布局(例如 QWERTY、Dvorak、西班牙语、InScript、中文等),并且需要考虑所有修饰键(
Shift、Alt等)和死键状态。 - key value
-
键值是与处于特定状态的键相关联的字符值或多字符字符串(例如
"Enter"、"Tab"或"MediaTrackNext")。每个键在任何时刻都有一个键值,无论其是否具有字符值。这包括控制键、功能键、修饰键、死键以及任何其他键。任意给定键在任意给定时间的键值取决于键映射。 - modifier key
-
修饰键会改变键的正常行为,例如生成不同大小写的字符(如
Shift键),或改变该键触发的功能(如Fn或Alt键)。有关修饰键的更多信息,请参阅 § 4.3.1 修饰键,并参考 [UIEvents-Key] 中的修饰键表以获取有效修饰键的列表。 - namespace URI
-
命名空间 URI是标识 XML 命名空间的 URI。在 [XML-Names11] 中称为命名空间名。另请参阅关于 DOM API 中 URI 与命名空间 URI 处理和比较的第 1.3.2 节 DOM URIs 与第 1.3.3 节 XML 命名空间。
- QWERTY
-
QWERTY(发音为
ˈkwɜrti
)是一种常见的键盘布局,因字母键顶排的前五个字符键为 Q、W、E、R、T、Y 而得名。还有许多其他流行的键盘布局(包括 Dvorak 和 Colemak 布局),大多数是为本地化或人体工程学设计的。 - root element
-
文档的第一个元素节点,其余所有元素都是该节点的子节点。即文档元素。
- text composition system
-
一种软件组件,用于解释某种形式的替代输入(例如输入法编辑器、语音处理器或手写识别系统)并将其转换为文本。
- Unicode character categories
-
为每个 Unicode 代码点定义的一般类别值的子集。该子集包含所有字母(Ll、Lm、Lo、Lt、Lu)、数字(Nd、Nl、No)、标点(Pc、Pd、Pe、Pf、Pi、Po、Ps)和符号(Sc、Sk、Sm、So)类别值。
- un-initialized value
-
任何事件属性(例如
bubbles或currentTarget)在使用initEvent()初始化事件之前的值。事件的未初始化值适用于在使用方法createEvent()创建新事件之后立即的状态。