1. 简介
1.1. 概述
UI 事件的设计有两个主要目标。第一个目标是设计一个 事件 系统,允许注册 事件监听器 并描述通过树结构的事件流。此外,该规范还将为用户界面控制和文档变动通知提供标准的事件模块,包括为这些事件模块中的每一个定义上下文信息。
UI 事件的第二个目标是提供当前现有浏览器所使用的事件系统的公共子集。这旨在促进现有脚本和内容的可互操作性。并不预期该目标能完全实现向后兼容。然而,本规范在可能的情况下尝试实现这一点。
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 核心规范 [DOM-Level-3-Core] 的背景下理解,并且适用于 DOM 实现的一般性考虑事项。例如,命名空间 URI 的处理在 XML 命名空间 中进行了讨论。有关 一致性 的更多信息,请参阅 DOM Level 3 核心规范 [DOM-Level-3-Core]。一个 用户代理 不需要为了符合本规范而完全符合另一个规范,但必须符合本规范中所引用的其他规范的特定部分(例如,一个符合 UI 事件的 用户代理 必须支持 [WebIDL] 中定义的 DOMString 数据类型,但为了符合 UI 事件,不需要支持 [WebIDL] 中定义的每个方法或数据类型)。
本规范为不同的 用户代理、规范和内容作者定义了若干类一致性。
1.2.1. Web 浏览器及其他动态或交互式 用户代理
一个动态或交互式的 用户代理,在此处称为“浏览器”(无论是 Web 浏览器、辅助技术 (AT) 应用还是其他类似程序),若其支持以下内容,则符合 UI 事件:
-
[DOM-Level-3-Core] 中定义的核心模块
-
本规范中定义的所有接口和事件及其相关的处理方法、属性和语义,但不包括那些标记为 已弃用 的部分(一个符合要求的用户代理可以出于向后兼容性而实现已弃用的接口、事件或 API,但为了符合要求,并不要求这样做)
-
[UIEvents-Key] 和 [UIEvents-Code] 中定义的完整
key和code值集(取决于平台可用性),以及 -
本规范中定义的所有其他规范性要求。
符合要求的浏览器必须在满足该 事件类型 定义的条件时,分发 (dispatch) 适用于给定 EventTarget 的事件。
如果浏览器实现了本文档指定的接口和相关 事件类型,则该浏览器特别符合 UI 事件。
符合要求的浏览器必须支持脚本、声明式交互或某种其他以本规范所描述的方式检测和分发事件的方法,并且必须支持为该 事件类型 指定的 API。
除了满足所有其他一致性标准外,符合要求的浏览器可以出于与现有内容的向后兼容性而实现本规范中标记为 已弃用 的功能,但不鼓励这种实现。
符合要求的浏览器还可以支持本规范中未发现的、但使用了本规范中定义的接口、事件或其他功能的功能,并且可以实现适用于该实现的附加接口和 事件类型。此类功能可以在未来的规范中进行标准化。
不符合本规范所有要求部分的浏览器不得声称符合 UI 事件。这种符合本规范部分内容的实现可以声称符合那些特定的部分。
符合要求的浏览器还必须是本规范中 IDL 片段的符合实现的 (conforming implementation),如 Web IDL 规范 [WebIDL] 中所述。
1.2.2. 创作工具
如果内容创作工具生成的内容以本规范定义的方式一致地使用 事件类型,则该工具符合 UI 事件。
内容创作工具不得针对其生成的、使用了本规范中标记为 已弃用 功能的内容声称符合 UI 事件。
符合要求的内容创作工具应该向内容作者提供一种方法,以在正在生成的内容文档中使用适用于所有 宿主语言 的所有 事件类型 和接口。
1.2.3. 内容作者和内容
如果内容以本规范定义的方式一致地使用 事件类型,则内容 作者 创建的内容即为符合要求的 UI 事件内容。
内容作者不应使用本规范中标记为 已弃用 的功能,而应依赖本规范及其他地方定义的替代机制。
符合要求的内容必须按照本规范中的描述使用接口和 事件类型 的语义。
建议内容作者遵循 无障碍 和 国际化 指南规范中描述的最佳实践。
1.2.4. 规范和宿主语言
如果某规范或 宿主语言 引用并使用了 [DOM] 中定义的事件流机制、接口、事件或其他功能,并且没有以不兼容的方式扩展这些功能,则该规范或宿主语言符合 UI 事件。
如果某规范或 宿主语言 引用并使用了本文档指定的接口和相关 事件类型,则它特别符合 UI 事件。符合要求的规范可以定义适用于该规范的额外接口和 事件类型,或者可以以不与本规范中那些接口和 事件类型 的定义相矛盾或冲突的方式扩展 UI 事件接口和 事件类型。
引用 UI 事件的规范或 宿主语言 不应使用或推荐使用本规范中标记为 已弃用 的功能,而应使用或推荐使用该功能的指定替代品(如有)。
2. 文体惯例
本规范遵循 建议的 W3C 规范惯例,并附带以下补充:
-
键上印制的 键帽 (key cap) 显示为
↓、=或Q。这用于从用户的角度指代按键,而不考虑生成的KeyboardEvent中的key和code值。 -
代表字符的字形显示为:
"𣧂"。 -
Unicode 字符编码显示为:
U+003d。 -
由按键生成的按键值名称(即
KeyboardEvent.key的值)显示为:"ArrowDown"、"="、"q"或"Q"。 -
与物理按键相关联的按键代码名称(即
KeyboardEvent.code的值)显示为:"ArrowDown"、"Equal"或"KeyQ"。
此外,本规范中某些术语具有特定含义。术语“实现 (implementation)”适用于实现本规范的浏览器、内容创作工具或其他 用户代理,而内容作者是编写脚本或代码的人,他们利用本规范中描述的接口、方法、属性、事件和其他功能来制作 Web 应用,用户则是该实现中这些 Web 应用的使用者。
最后
这是一个注释。
这是一个开放问题。
这是一个警告。
interface Example {
// This is an IDL definition.
};
3. 基本事件接口
[DOM] 中定义的基本事件接口是 UI 事件的基础。实现必须始终支持这些基本事件接口。
-
Event接口及其以下常量、方法和属性:-
NONE常量 -
AT_TARGET常量 -
type属性 -
target属性 -
eventPhase属性 -
bubbles属性 -
cancelable属性 -
composed属性 -
timeStamp属性 -
isTrusted属性 -
initEvent()方法
-
-
CustomEvent接口及其以下方法和属性:-
detail属性
-
EventTarget接口及其以下方法: -
EventListener接口及其handleEvent()方法 -
Document接口的createEvent()方法
本规范定义的事件类型派生自这些基本接口,并且必须继承它们所派生的接口的所有属性、方法和常量。
下表描述了本规范所描述接口的继承结构。
3.1. 事件类型列表
每个事件必须与一个类型相关联,该类型称为 事件类型 (event type),并作为事件对象上的 type 属性提供。事件类型必须是 DOMString 类型。
根据 DOM 支持的级别或用于显示(例如屏幕)或交互(例如鼠标、键盘、触摸屏或语音)的设备,这些事件类型可以由实现生成。当与 [XML] 或 [HTML5] 应用一起使用时,这些语言的规范可能会限制与事件类型相关联的语义和范围(特别是可能的 事件目标)。请参考定义所用语言的规范,以查找这些限制或查找本文档中未定义的事件类型。
下表提供了本规范中描述的事件类型的说明性摘要。
| 事件类型 | 同步 / 异步 | 冒泡阶段 | 可信事件目标类型 | DOM 接口 | 可取消 | 默认操作 |
|---|---|---|---|---|---|---|
abort (中止)
| 同步 | No | Window, Element | Event
| No | 无 |
beforeinput
| 同步 | 是 | 元素 | InputEvent
| 是 | 更新 DOM 元素 |
blur
| 同步 | No | Window, Element | FocusEvent
| No | 无 |
compositionstart
| 同步 | 是 | 元素 | CompositionEvent
| 是 | 显示 文本组合系统 候选项窗口 |
compositionupdate
| 同步 | 是 | 元素 | CompositionEvent
| No | 无 |
compositionend
| 同步 | 是 | 元素 | CompositionEvent
| No | 无 |
error
| 异步 | No | Window, Element | Event
| No | 无 |
focus
| 同步 | No | Window, Element | FocusEvent
| No | 无 |
focusin
| 同步 | 是 | Window, Element | FocusEvent
| No | 无 |
focusout
| 同步 | 是 | Window, Element | FocusEvent
| No | 无 |
input (输入)
| 同步 | 是 | 元素 | InputEvent
| No | 无 |
keydown
| 同步 | 是 | 元素 | KeyboardEvent
| 是 | 不同:触发 beforeinput 和 input 事件;启动 文本组合系统;blur 和 focus 事件;keypress 事件(如果支持);激活行为;其他事件 |
keyup
| 同步 | 是 | 元素 | KeyboardEvent
| 是 | 无 |
load
| 异步 | No | Window, Document, Element | Event
| No | 无 |
select
| 同步 | 是 | 元素 | Event
| No | 无 |
unload
| 同步 | No | Window, Document, Element | Event
| No | 无 |
有关本规范中已弃用的事件列表,请参阅本文档末尾的 遗留事件类型 附录。
以下是解读上述表格的一种方式: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 . viewview属性标识了生成事件的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,要初始化的
UIEvent -
eventType,包含事件类型的 DOMString
-
eventTarget,事件的
EventTarget -
bubbles,如果此事件冒泡则为 true
-
cancelable,如果此事件可取消则为 true
- 输出:
-
无
-
初始化基本的
Event属性-
使用 event、eventType、bubbles 和 cancelable 初始化一个 Event
-
设置 event.
target= eventTarget
-
-
初始化以下公共属性
-
初始化以下历史属性
-
设置 event.
which= 0(同时被MouseEvent和KeyboardEvent使用)
-
3.2.3. UIEvent 类型
用户界面事件类型如下所示。其中一些事件如果是从用户界面生成,则使用 UIEvent 接口,否则使用 Event 接口,详情见每个事件。
3.2.3.1. load
| 类型 | load
|
|---|---|
| Interface | 如果是从用户界面生成则使用 UIEvent,否则使用 Event。 |
| 同步 / 异步 | 异步 |
| 冒泡 | No |
| 受信任的目标 | Window, Document, Element |
| 可取消 | No |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当 DOM 实现完成加载资源(如文档)以及任何依赖资源(如图像、样式表或脚本)时,用户代理必须分发此事件。如果加载它们的资源仍然可以通过 DOM 访问,则加载失败的依赖资源不得阻止此事件触发。如果分发了此事件类型,实现必须至少在 Document 节点上分发此事件。
由于历史原因,文档内部资源(例如图像)的 load 事件在 HTML 实现中不包含传播路径中的 Window。更多信息请参阅 [HTML5]。
3.2.3.2. unload
| 类型 | unload
|
|---|---|
| Interface | 如果是从用户界面生成则使用 UIEvent,否则使用 Event。 |
| 同步 / 异步 | 同步 |
| 冒泡 | No |
| 受信任的目标 | Window, Document, Element |
| 可取消 | No |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当 DOM 实现从环境中移除资源(如文档)或任何依赖资源(如图像、样式表、脚本)时,用户代理必须分发此事件。文档必须在此事件类型分发后卸载。如果分发了此事件类型,实现必须至少在 Document 节点上分发此事件。
3.2.3.3. abort
| 类型 | abort (中止)
|
|---|---|
| Interface | 如果是从用户界面生成则使用 UIEvent,否则使用 Event。 |
| 同步 / 异步 | 同步 |
| 冒泡 | No |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当资源加载中止时(例如用户在加载仍在进行时取消加载),用户代理必须分发此事件。
3.2.3.4. error
| 类型 | error
|
|---|---|
| Interface | 如果是从用户界面生成则使用 UIEvent,否则使用 Event。 |
| 同步 / 异步 | 异步 |
| 冒泡 | No |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当资源加载失败或已加载但无法根据其语义进行解释(如无效图像、脚本执行错误或格式不正确的 XML)时,用户代理必须分发此事件。
3.2.3.5. select
| 类型 | select
|
|---|---|
| Interface | 如果是从用户界面生成则使用 UIEvent,否则使用 Event。 |
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | No |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当用户选择某些文本时,用户代理必须分发此事件。此事件在选择发生后分发。
本规范不提供用于访问所选文本的上下文信息。在适用的情况下,宿主语言应定义有关用户如何选择内容(考虑到国际语言惯例)、在何时分发 select 事件以及内容作者如何访问用户所选内容的规则。
为了访问用户所选内容,内容作者将使用宿主语言的原生功能,例如 HTML 编辑 API [Editing] 的 Document.getSelection() 方法。
select 事件可能并非在所有语言的所有元素中都可用。例如,在 [HTML5] 中,select 事件只能在表单 input 和 textarea 元素上分发。实现可以在认为适用的任何上下文中分发 select 事件,包括表单控件之外的文本选择,或图像或标记选择(如在 SVG 中)。
3.3. 焦点事件
此接口及其相关事件类型和 § 3.3.2 焦点事件顺序 是根据 用户代理无障碍指南 2.0 (UAAG 2.0) [UAAG20] 中定义的概念和指南设计的,特别关注 焦点机制 和 焦点术语表条目 中定义的术语。
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,具体取决于事件类型。出于嵌套浏览上下文的安全考虑,在通过 tab 键进入或移出嵌套上下文时,相关的
EventTarget应为null。此属性的 未初始化值 必须为
null。
3.3.1.2. FocusEventInit
dictionary :FocusEventInit UIEventInit {EventTarget ?=relatedTarget null ; };
FocusEventInit . relatedTargetrelatedTarget应初始化为失去焦点的元素(对于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
|
|---|---|
| Interface | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | No |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当 事件目标 失去焦点时,用户代理必须分发此事件。在分发此事件类型之前,焦点必须从该元素中移除。此事件类型与 focusout 类似,但不冒泡。
3.3.4.2. focus
| 类型 | focus
|
|---|---|
| Interface | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | No |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当 事件目标 获得焦点时,用户代理必须分发此事件。在分发此事件类型之前,焦点必须赋予该元素。此事件类型与 focusin 类似,但不冒泡。
3.3.4.3. focusin
| 类型 | focusin
|
|---|---|
| Interface | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当 事件目标 获得焦点时,用户代理必须分发此事件。该 事件目标 必须是获得焦点的元素。focus 事件必须在分发此事件类型之前触发。此事件类型与 focus 类似,但会冒泡。
3.3.4.4. focusout
| 类型 | focusout
|
|---|---|
| Interface | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当 事件目标 失去焦点时,用户代理必须分发此事件。该 事件目标 必须是失去焦点的元素。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]。字符应按照 [UAX15] 中定义的 Unicode 规范化形式 NFC 进行规范化。此属性可以包含 空字符串。此属性的 未初始化值 必须为
null。 isComposing, 类型为 boolean, 只读-
如果输入事件作为组合会话的一部分发生,则为
true,即在compositionstart事件之后且在相应的compositionend事件之前。此属性的 未初始化值 必须为
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
|
|---|---|
| Interface | InputEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Element(具体来说:如 HTMLInputElement 等控件类型)或任何启用了 contenteditable 属性的 Element |
| 可取消 | 是 |
| 已组合 | 是 |
| 默认操作 | 更新 DOM 元素 |
| 上下文 (受信任事件) |
|
用户代理在 DOM 即将更新时必须分发此事件。
3.4.3.2. input
| 类型 | input (输入)
|
|---|---|
| Interface | InputEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Element(具体来说:如 HTMLInputElement 等控件类型)或任何启用了 contenteditable 属性的 Element |
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
用户代理必须在 DOM 更新后立即分发此事件。
3.5. 键盘事件
键盘事件与设备相关,即它们依赖于输入设备的功能以及它们在操作系统中的映射方式。有关更多详细信息,包括键盘事件与组合事件结合使用的示例,请参阅 键盘事件和键值。根据字符生成设备的不同,可能不会生成键盘事件。
键盘事件只是提供文本输入的一种模态。对于编辑场景,还可以考虑使用 InputEvent 作为键盘事件的替代方案(或补充)。
3.5.1. KeyboardEvent 接口
在本规范中引入
KeyboardEvent 接口提供了与键盘设备相关的特定上下文信息。每个键盘事件都使用一个值引用一个键。键盘事件通常针对当前获得焦点的元素。
KeyboardEvent 接口为一些常见的修饰键提供了便捷的属性:ctrlKey, shiftKey, altKey, metaKey。这些属性等效于使用 getModifierState() 方法并分别传入 Control, Shift, Alt 或 Meta 参数。
要创建 KeyboardEvent 接口的实例,请使用 KeyboardEvent 构造函数,并传入可选的 KeyboardEventInit 字典。
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属性与传统的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,顺序如上,速率由系统配置决定。对于具有“长按键”行为的移动设备,第一个repeat属性值为true的键盘事件必须作为“长按”的指示。按键必须被按住多久才能开始重复取决于配置。此属性的 未初始化值 必须为
false。 isComposing, 类型为 boolean,只读-
如果键事件发生在组合会话期间(即在
compositionstart事件之后且在相应的compositionend事件之前),则为true。此属性的 未初始化值 必须为
false。 getModifierState(keyArg)- 使用键值查询修饰符的状态。
如果它是修饰键并且修饰符已激活,则返回
true;否则返回false。- DOMString keyArg
- 修饰键的值。有效的 修饰键 定义在 [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] 中定义的代码值之一。 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 事件标准的实现中,内容作者可以使用 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. 事件修饰符初始化程序
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- 如果
Control键修饰符被视为活动状态,则将MouseEvent或KeyboardEvent对象的ctrlKey属性初始化为true,否则为false。当为
true时,实现还必须初始化事件对象的键修饰符状态,使得当传入参数Control时,调用getModifierState()或getModifierState()必须返回true。 shiftKey, 类型为 boolean,默认为false- 如果
Shift键修饰符被视为活动状态,则将MouseEvent或KeyboardEvent对象的shiftKey属性初始化为true,否则为false。当为
true时,实现还必须初始化事件对象的键修饰符状态,使得当传入参数Shift时,调用getModifierState()或getModifierState()必须返回true。 altKey, 类型为 boolean,默认为false- 如果
Alt(备选)(或Option)键修饰符被视为活动状态,则将MouseEvent或KeyboardEvent对象的altKey属性初始化为true,否则为false。当为
true时,实现还必须初始化事件对象的键修饰符状态,使得当传入参数Alt时,调用getModifierState()或getModifierState()必须返回true。 metaKey, 类型为 boolean,默认为false- 如果
Meta键修饰符被视为活动状态,则将MouseEvent或KeyboardEvent对象的metaKey属性初始化为true,否则为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. 用户代理级状态
UA 必须维护以下在整个用户代理中共享的值:
一种 键修饰符状态(初始为空),用于跟踪系统上可用的每个 修饰键 的当前状态。
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 元素(如果可用),否则为 根元素。
事件目标可能会在不同的键事件之间发生变化。例如,Tab 键的 keydown 事件的 事件目标 很可能与同一按键上的 keyup 事件不同。
3.5.6. 键盘事件类型
3.5.6.1. keydown
| 类型 | keydown
|
|---|---|
| Interface | KeyboardEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | 是 |
| 已组合 | 是 |
| 默认操作 | 各异:beforeinput 和 input 事件;启动 文本组合系统;blur 和 focus 事件;keypress 事件(如果支持);激活行为;其他事件 |
| 上下文 (受信任事件) |
|
用户代理在按键被按下时必须分发此事件。keydown 事件类型与设备相关,依赖于输入设备的功能以及它们在操作系统中的映射方式。此事件类型必须在 键映射 之后生成。此事件类型必须在与同一按键相关联的 beforeinput、input 和 keyup 事件之前分发。
keydown 事件的默认动作取决于具体的键
-
如果该键与字符相关联,则默认动作必须是分发
beforeinput事件,随后分发input事件。在键与多个字符关联(例如宏或某些死键序列)的情况下,默认动作必须是为每个字符分发一组beforeinput/input事件 -
如果该键与 文本组合系统 相关联,则默认动作必须是启动该系统
-
如果该键是
Tab键,则默认动作必须是将文档焦点从当前获得焦点的元素(如果有)切换到新的焦点元素,如 焦点事件类型 所述 -
如果该键是
Enter或(空格)键,且当前焦点在状态改变元素上,则默认动作必须是分发click事件;如果 用户代理 支持该事件类型,则还需分发DOMActivate事件。
如果此事件被取消,则不应分发相关的事件类型,也不应执行相关的动作。
keydown 和 keyup 事件传统上与检测任何按键相关,而不限于那些产生 字符值 的按键。
3.5.6.2. keyup
| 类型 | keyup
|
|---|---|
| Interface | KeyboardEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | 是 |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
|
用户代理在按键被释放时必须分发此事件。keyup 事件类型与设备相关,依赖于输入设备的功能以及它们在操作系统中的映射方式。此事件类型必须在 键映射 之后生成。此事件类型必须在与同一按键相关联的 keydown、beforeinput 和 input 事件之后分发。
3.6. 组合事件
组合事件提供了一种以不同于键盘事件的方式输入文本的手段,以便使用键盘上可能不常见的字符。例如,组合事件可用于向字符添加变音符号(即使标准美式键盘上没有),从基础组件或类别构建多种亚洲语言的语标,从移动设备键盘上的组合按键中选择词语,或者使用语音识别处理器将语音命令转换为文本。有关如何将组合事件与键盘事件结合使用的示例,请参阅 § 4 键盘事件和键值。
从概念上讲,一个组合会话由一个 compositionstart 事件、一个或多个 compositionupdate 事件和一个 compositionend 事件组成,data 属性的值在每次会话的事件链的每个“阶段”之间保持不变。
注意:当组合会话处于活动状态时,如果键盘是与组合会话配合使用的输入设备,则键盘事件仍可分发到 DOM。有关相关事件顺序,请参见 compositionstart 事件详细信息和 IME 部分。
并非所有 IME 系统或设备都会向 DOM 公开必要的数据,因此活动的组合字符串(“阅读窗口”或“候选选择菜单选项”)可能无法通过此接口获取,在这种情况下,选择内容可以用 空字符串 表示。
3.6.1. Interface CompositionEvent
在本规范中引入
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]。字符应按照 [UAX15] 中定义的 Unicode 标准化形式 NFC 进行标准化。此属性可以是 空字符串。此属性的 未初始化值 必须为
""(空字符串)。
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. 组合期间的输入事件
在组合会话期间,必须在发送 beforeinput 之后但在发送 input 事件之前分发 compositionupdate。
| 事件类型 | 注 | |
|---|---|---|
| 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
| 类型 | compositionstart
|
|---|---|
| Interface | CompositionEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | 是 |
| 已组合 | 是 |
| 默认操作 | 当启用 文本组合系统 时启动新的组合会话 |
| 上下文 (受信任事件) |
用户代理在启用 文本组合系统 且新的组合会话即将开始(或已经开始,取决于 文本组合系统)以为组合文本段落做准备时,必须分发此事件。此事件类型与设备相关,且可能依赖于文本转换系统的功能及其在操作系统中的映射方式。当使用键盘为输入法编辑器提供输入时,此事件类型在 keydown 事件之后生成,但语音或手写识别系统可能在没有键盘事件的情况下发送此事件类型。某些实现可能使用文档中当前选定的文本(用于编辑和替换)来填充 compositionstart 事件的 data 属性。否则,data 属性的值必须是 空字符串。
此事件必须在 文本组合系统 开始新的组合会话之前以及由于组合过程导致 DOM 被修改之前立即分发。此事件的默认动作是 文本组合系统 开始新的组合会话。如果此事件被取消,文本组合系统 应放弃当前的组合会话。
取消 compositionstart 事件类型 不同于取消 文本组合系统 本身(例如通过点击取消按钮或关闭 IME 窗口)。
某些 IME 不支持取消正在进行的组合会话(例如 GTK 目前没有这样的 API)。在这些情况下,调用 preventDefault() 将不会停止此事件的默认动作。
3.6.7.2. compositionupdate
| 类型 | compositionupdate
|
|---|---|
| Interface | CompositionEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当文本组合系统使用新字符更新其活动文本段落(该更新反映在 data 字符串中)时,用户代理应(SHOULD)触发此事件。
在将正在进行的组合与输入控件保持同步的文本组合系统中,必须(MUST)在更新控件之前触发 compositionupdate 事件。
一些文本组合系统可能不会将此信息暴露给 DOM,在这种情况下,此事件在组合过程中不会触发。
如果组合会话被取消,此事件将在 compositionend 事件之前立即触发,并且 data 属性将被设置为空空字符串。
3.6.7.3. compositionend
| 类型 | compositionend
|
|---|---|
| Interface | CompositionEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当文本组合系统完成或取消当前组合会话时,用户代理必须(MUST)触发此事件;compositionend 事件必须(MUST)在控件更新后触发。
此事件在文本组合系统完成组合会话后立即触发(例如:IME 关闭、最小化、失去焦点或以其他方式被取消,且焦点切回到用户代理)。
4. 键盘事件和键值
本节包含有关键盘事件的必要信息。
-
键盘布局、映射和键值的解释。
-
键之间的关系,例如死键(dead keys)或修饰键。
-
键盘事件与默认行为之间的关系。
-
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 使用 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属性旨在服务于关心所按按键含义的用户,它会考虑当前的键盘布局(以及 IME;死键被赋予唯一的key值)。使用场景示例:检测组合键或纯修饰键(例如,执行快捷键操作)。codecode属性旨在服务于关心用户按下了哪个物理键的用户,无需应用任何布局修改。使用场景示例:检测 WASD 键(例如,游戏中的移动控制)或捕获所有按键(例如,远程桌面客户端将所有按键发送到远程主机)。
4.2.3. code 示例
| 键盘布局 | KeyboardEventkey
| KeyboardEventcode
| 注 |
|---|---|---|---|
| 美式(US) | "Alt"
| "AltLeft"
| DOM_KEY_LOCATION_LEFT
|
| 法语 | "Alt"
| "AltLeft"
| DOM_KEY_LOCATION_LEFT
|
| 美式(US) | "Alt"
| "AltRight"
| DOM_KEY_LOCATION_RIGHT
|
| 法语 | "AltGraph"
| "AltRight"
| DOM_KEY_LOCATION_RIGHT
|
在此示例中,检查 key 属性允许匹配 Alt 而无需关心按下了哪个 Alt 键(左或右)。检查 code 属性允许匹配右 Alt 键("AltRight"),而无需关心当前使用了哪种布局。
请注意,在法语示例中,Alt 和 AltGraph 键保留了它们的左右位置,即使每种键只有一个。
| 键盘布局 | KeyboardEventkey
| KeyboardEventcode
| 注 |
|---|---|---|---|
| 美式(US) | "'"
| "Quote"
| |
| 日语 | ":"
| "Quote"
| |
| 美式国际(US Intl) | "Dead"
| "Quote"
|
"2" 键(按下和不按下 Shift 的情况)在各种键盘布局上。| 键盘布局 | KeyboardEventkey
| KeyboardEventcode
| 注 |
|---|---|---|---|
| 美式(US) | "2"
| "Digit2"
| |
| 美式(US) | "@"
| "Digit2"
| shiftKey
|
| 英国(UK) | "2"
| "Digit2"
| |
| 英国(UK) | """
| "Digit2"
| shiftKey
|
| 法语 | "é"
| "Digit2"
| |
| 法语 | "2"
| "Digit2"
| shiftKey
|
无论当前的区域设置或修饰键状态如何,在美式键盘上按下标记为 "2" 的键,code 属性中总是会产生 "Digit2"。
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"
|
请注意,"2" 键在 keydown 和 keyup 事件中,key 属性包含的值不匹配。code 属性提供了一个不受当前修饰状态影响的一致值。
4.2.4. code 和虚拟键盘
code 属性在虚拟键盘(以及遥控器和和弦键盘)上的用处并不那么明显。通常,如果虚拟键盘(或遥控器)正在模仿标准键盘的布局和功能,那么它也必须(MUST)适当地设置 code 属性。对于不模仿标准键盘布局的键盘,code 属性可以设置为标准键盘上最接近的匹配项,也可以保持未定义。
对于具有根据某些修饰状态产生不同值的按键的虚拟键盘,code 值应为设备处于出厂重置状态时按下按钮所生成的 key 值。
4.3. 键盘事件 key 值
键值是一个 DOMString,可用于通过其产生的值来指示键盘上的任何给定按键,无论其位置或状态如何。这些键值可以用作实现生成的键盘事件的返回值,也可以由内容作者用作输入值来指定所需的输入(例如用于键盘快捷键)。
有效的 key 值列表定义在 [UIEvents-Key] 中。
键值可用于检测已按下的键的值,使用 key 属性。内容作者可以检索大写或小写字母、数字、符号或其他产生字符的按键的字符值,以及控制键、修饰键、功能键或其他不产生字符的按键的键值。这些值可用于监控特定的输入字符串、结合其他输入(如鼠标)来检测并对修饰键输入采取行动、创建虚拟键盘或用于许多其他目的。
键值还可由内容作者用于字符串比较、作为合规宿主语言中标记属性(如 HTML accesskey)的值,或用于其他相关目的。合规的宿主语言应(SHOULD)允许内容作者使用键值的两种等效字符串值之一:字符值或键值。
虽然实现将独立于平台或键盘布局映射使用键的最相关值,但内容作者不能假设键盘设备有能力生成它们。当使用键盘事件和键值进行快捷键组合时,内容作者可以“考虑使用数字和功能键(F4, F5 等)而不是字母”([DWW95]),因为大多数键盘布局都会提供这些按键。
键值并不指示物理键盘上的特定键,也不反映印在键上的字符。键值指示事件的当前值,并考虑所有活动键和键输入模式(包括 Shift 模式)的当前状态,这反映在操作系统的键盘映射中并报告给实现。换句话说,在QWERTY键盘上标记为 O 的键,在未按下 Shift 的状态下具有键值 "o",在按下 Shift 的状态下具有键值 "O"。由于用户可以将他们的键盘映射到任意自定义配置,鼓励内容作者不要假设键的移位状态和非移位状态与字符表示的大写形式(upper-case or capital letters)和小写形式(lower-case or small letters)之间存在关系,而是鼓励使用 key 属性的值。例如,[UIEvents-Code] 中描述的标准“102”键盘布局说明了一种可能键盘布局上的一组可能的键映射。存在许多其他的映射,包括标准的和独特的。
为了简化死键支持,当操作系统的键盘映射正在处理死键状态时,死键序列的当前状态不会通过 key 属性报告。相反,报告的键值为 "Dead"。实现会生成组合事件,其中包含通过 data 属性报告的死键序列的中间状态。正如前一个示例所示,在QWERTY键盘上标记为 O 的键,在死键操作中添加元音变音符号(umlaut diacritic)的未按下 Shift 状态下,其 data 值为 "ö";在按下 Shift 状态下,其值为 "Ö"。
同样重要的是要注意,键事件状态和键值之间不是一对一的关系。一个特定的键值可能与多个键相关联。例如,许多标准键盘包含多个具有 Shift 键值的键(通常通过 location 值 DOM_KEY_LOCATION_LEFT 和 DOM_KEY_LOCATION_RIGHT 区分)或 8 键值(通常通过 location 值 DOM_KEY_LOCATION_STANDARD 和 DOM_KEY_LOCATION_NUMPAD 区分),用户自定义的键盘布局可能在多种键状态场景下重复任何键值(请注意,location 旨在用于标准键盘布局,并不总能指示有意义的区别)。
最后,任何给定字符表示的含义是上下文相关的且复杂的。例如,在某些上下文中,星号(star)符号("*")代表脚注或强调(当括号括起一段文本时)。然而,在某些文档或可执行程序中,它等同于数学乘法运算,而在其他文档或可执行程序中,该功能保留用于乘法符号("×",Unicode 值 U+00D7)或拉丁小写字母 "x"(由于许多键盘上缺乏乘法键以及符号 "×" 和 "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 事件的非移位值。| 事件类型 | 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 OS 上的 Backspace 键功能相同;但当被 Fn 键修饰时,它充当 Delete 键,并且 key 的值将匹配该键在当前修饰状态下最合适的功能。
4.3.2. 死键(Dead keys)
一些键盘输入使用死键来输入组合字符序列。与用户先输入基字符的手写序列不同,键盘输入需要在一个死键被按下时进入一种特殊状态,并仅在输入了有限数量的“合法”基字符之一时才输出字符。
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. 输入法编辑器(Input Method Editors)
本规范通过 CompositionEvent 接口和事件包含了输入法编辑器(IME)的模型。然而,组合事件和键盘事件并不一定是一对一的关系。例如,接收到 Accept 键值的 keydown 事件并不一定意味着当前在 IME 中选择的文本正在被接受,它仅表明发生了一次按键操作,与 IME 的“接受”功能脱节(在大多数 IME 系统中,该功能通常会导致 compositionend 事件)。键盘事件无法用于确定输入法编辑器的当前状态,该状态可通过 CompositionEvent 接口的 data 属性获取。此外,IME 系统和设备的功能各不相同,用于激活该功能的按键也不尽相同,因此 Convert 和 Accept 键可以由其他可用按键表示。键盘事件对应于键盘布局映射后输入设备生成的事件。
在某些实现或系统配置中,一些键事件或其值可能会被正在使用的 IME 抑制。
以下示例描述了使用日语输入法生成 Unicode 字符 "市"(汉字,CJK 统一表意文字的一部分)的可能按键序列。此示例假设已激活输入法编辑器并处于日语-罗马字输入模式。根据所使用的输入设备和 IME 的配置,键 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
| "詩"
| "poem" | ||
| DOM 已更新 | |||||
| 15 | input (输入)
| ||||
| 16 | keyup
| "Convert"
| true
| ||
| 17 | keydown
| "Convert"
| true
| 转换 | |
| 18 | beforeinput
| ||||
| 19 | compositionupdate
| "市"
| "city" | ||
| DOM 已更新 | |||||
| 20 | input (输入)
| ||||
| 21 | keyup
| "Convert"
| true
| ||
| 22 | keydown
| "Accept"
| true
| Accept | |
| 23 | compositionend
| "市"
| |||
| 24 | keyup
| "Accept"
| false
|
IME 组合也可以像以下示例一样取消,条件与前一个示例相同。根据所使用的输入设备和 IME 的配置,Cancel 键也可以被其他键替换,例如它可以是 U+001B(Escape 键)。
| 事件类型 | 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
| "詩"
| "poem" | ||
| 10 | keyup
| "Convert"
| true
| ||
| 11 | keydown
| "Convert"
| true
| 转换 | |
| 12 | compositionupdate
| "市"
| "city" | ||
| 13 | keyup
| "Convert"
| true
| ||
| 14 | keydown
| "Cancel"
| true
| Cancel(取消) | |
| 15 | compositionupdate
| ""
| |||
| 16 | compositionend
| ""
| |||
| 17 | keyup
| "Cancel"
| false
|
一些输入法编辑器(例如在 MacOS 操作系统上)可能会在取消组合之前将空字符串设置到组合数据属性中。
4.3.3.1. 输入法编辑器模式键
某些设备上的某些键旨在激活输入法编辑器功能,或更改活动输入法编辑器的模式。可以为不同的设备或语言模式定义用于此目的的自定义键。本规范为此目的定义的键包括:"Alphanumeric", "CodeInput", "FinalMode", "HangulMode", "HanjaMode", "Hiragana", "JunjaMode", "KanaMode", "KanjiMode", "Katakana", 和 "Romaji"。当按下其中一个键且当前未激活 IME 时,预期的适当 IME 将以该键指示的模式激活(如果可用)。如果按下该键时 IME 已经激活,则活动的 IME 可能会更改为指示的模式,或者可能会启动不同的 IME,或者在设备和应用程序特定基础上忽略该按键。
本规范还定义了其他旨在专门与输入法编辑器配合操作的键:"Accept", "AllCandidates", "Cancel", "Convert", "Compose", "Zenkaku" (全角), "Hankaku" (半角), "NextCandidate", "NonConvert", 和 "PreviousCandidate"。这些键的功能未在本规范中定义——有关输入法编辑器功能的详细信息,请参阅其他资源。
具有输入法编辑器功能的键并不局限于该目的,还可以具有其他设备或实现特定的目的。
4.3.4. 默认行为和可取消的键盘事件
取消 keydown 事件的默认行为不得影响其相应的 keyup 事件,但必须防止生成相应的 beforeinput 和 input(以及如果支持的话,keypress)事件。以下示例描述了在美式键盘上使用美式映射生成 Unicode 字符 Q(拉丁大写字母 Q)时可能发生的按键序列。
| 事件类型 | KeyboardEventkey
| InputEventdata
| 修饰符 | 注 | |
|---|---|---|---|---|---|
| 1 | keydown
| "Shift"
| shiftKey
| ||
| 2 | keydown
| "Q"
| shiftKey
| 默认行为被阻止,例如通过调用 preventDefault()。 | |
不会生成任何 beforeinput 或 input(或如果支持的 keypress)事件。
| |||||
| 3 | keyup
| "Q"
| shiftKey
| ||
| 4 | keyup
| "Shift"
|
如果该键是修饰键,则按键仍必须计入修饰符状态。以下示例描述了在美式键盘上使用美式映射生成 Unicode 字符 Q(拉丁大写字母 Q)时可能发生的按键序列。
| 事件类型 | KeyboardEventkey
| InputEventdata
| 修饰符 | 注 | |
|---|---|---|---|---|---|
| 1 | keydown
| "Shift"
| shiftKey
| 默认行为被阻止,例如通过调用 preventDefault()。 | |
| 2 | keydown
| "Q"
| shiftKey
| ||
| 3 | beforeinput
| "Q"
| |||
| 4 | input (输入)
| ||||
| 5 | keyup
| "Q"
| shiftKey
| ||
| 6 | keyup
| "Shift"
|
如果该键是几个按键序列的一部分,无论它是死键还是有助于输入法编辑器序列的键,仅当在 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. 窗口级状态
UA 必须维护以下在窗口中共享的值:
一个 最后鼠标移动 值(最初未定义),记录最后一次 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. 遗留键和鼠标事件属性
本节是非规范性的。以下属性已过时,仅应由需要与需要这些键盘事件的遗留软件兼容的用户代理实现。
这些功能从未正式指定,目前的浏览器实现存在显著差异。大量依赖检测用户代理并采取相应行动的遗留内容(包括脚本库)意味着,任何正式化这些遗留属性和事件的尝试都可能破坏与它修复或启用的一样多的内容。此外,这些属性不适合国际化使用,也没有解决无障碍性问题。
因此,本规范没有对处理键盘输入时常用的事件和属性进行规范定义,尽管它们为了与遗留内容兼容,可能存在于用户代理中。作者应(SHOULD)使用 key 属性,而不是 charCode 和 keyCode 属性。
然而,为了记录这些功能的当前状态及其与规范事件和属性的关系,本节提供了一个信息性描述。对于支持这些属性和事件的实现,建议使用本节中提供的定义。
7.1. 遗留 UIEvent 补充接口
本节为非规范性内容
用户代理传统上包含了 which 属性,以便 KeyboardEvent 和 MouseEvent 可以记录补充事件信息。
本规范的早期版本在 KeyboardEvent 和 MouseEvent 上直接定义了单独的 which 属性,而不是在 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(补充)
在 UIEvent 中支持 which 的浏览器也应将以下成员添加到 UIEventInit 字典中。
部分 UIEventInit 字典是 UIEventInit 字典的提示性扩展,它添加了 which 成员以初始化相应的 UIEvent 属性。
partial dictionary UIEventInit {unsigned long which = 0; };
which, 类型为 unsigned long,默认值为0- 初始化
UIEvent的which属性。
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.charCode = 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 旧版键模型。
7.2.2. 接口 KeyboardEventInit(补充)
在 KeyboardEvent 中支持 keyCode 和 charCode 的浏览器也应将以下成员添加到 KeyboardEventInit 字典中。
部分 KeyboardEventInit 字典是 KeyboardEventInit 字典的提示性扩展,它添加了 charCode 和 keyCode 成员以初始化相应的 KeyboardEvent 属性。
partial dictionary KeyboardEventInit { // The following support legacy user agentsunsigned long charCode = 0;unsigned long keyCode = 0; };
charCode, 类型为 unsigned long,默认值为0- 将
KeyboardEvent的charCode属性初始化为事件字符的 Unicode 码点。 keyCode, 类型为 unsigned long,默认值为0- 将
KeyboardEvent的keyCode属性初始化为表示与所按按键关联的未修改标识符的系统和实现相关数值代码。
7.3. 旧版键模型
本节为非规范性内容
不同实现对于在不同事件类型中这些属性暴露的值有所不同。实现可以选择在 keyCode 属性中同时暴露虚拟键码和字符码(合并模型),或者报告单独的 keyCode 和 charCode 属性(分离模型)。
7.3.1. 如何确定 keyCode 用于 keydown 和 keyup 事件
keydown 或 keyup 事件的 keyCode 计算如下:
-
如果可用,从操作系统的事件信息中读取虚拟键码。
-
如果输入法编辑器(IME)正在处理按键输入且事件为
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 | |
| 控制 | 17 | |
| Alt 键 | 18 | |
| 大写锁定键 (CapsLock) | 20 | |
| 转义键 (Escape) | 27 | Esc 键 |
| 空格 | 32 | |
| 向上翻页键 (PageUp) | 33 | |
| 向下翻页键 (PageDown) | 34 | |
| 结束 (End) | 35 | |
| 主页 | 36 | |
| 左箭头键 (ArrowLeft) | 37 | |
| 上箭头键 (ArrowUp) | 38 | |
| 右箭头键 (ArrowRight) | 39 | |
| 下箭头键 (ArrowDown) | 40 | |
| 删除 | 46 | Del(∇) |
7.3.4. 可选的固定虚拟键码
以下标点符号字符在键盘布局之间可能会改变虚拟码,但报告这些值对于期望美式英语键盘布局的旧版内容来说可能具有更好的兼容性:
| 键 | 字符 | 虚拟键 代码 |
|---|---|---|
| 分号 (;) | ";"
| 186 |
| Colon | ":"
| 186 |
| 等号 (=) | "="
| 187 |
| 加号 (+) | "+"
| 187 |
| Comma | ","
| 188 |
| 小于号 (<) | "<"
| 188 |
| 减号 | "-"
| 189 |
| 下划线 (_) | "_"
| 189 |
| 句号 (.) | "."
| 190 |
| 大于号 (>) | ">"
| 190 |
| 正斜杠 (/) | "/"
| 191 |
| 问号 (?) | "?"
| 191 |
| 反引号 (`) | "`"
| 192 |
| 波浪号 | "~"
| 192 |
| 左方括号 ([) | "["
| 219 |
| 左花括号 ({) | "{"
| 219 |
| Backslash → 反斜杠 | "\"
| 220 |
| 竖线 (|) | "|"
| 220 |
| 右方括号 (]) | "]"
| 221 |
| 右花括号 (}) | "}"
| 221 |
| 单引号 (') | "'"
| 222 |
| 双引号 (") | """
| 222 |
8. 旧版事件类型
本节具有规范性。以下事件类型已过时,仅应由需要与旧版软件兼容的用户代理实现。
本节旨在记录这些功能的当前状态及其与规范事件的关系。对于确实支持这些事件的实现,建议使用本节中提供的定义。
下表提供了本规范中已弃用的事件类型的提示性摘要。它们包含在此处仅供参考和完整性。
| 事件类型 | 同步 / 异步 | 冒泡阶段 | 可信事件目标类型 | DOM 接口 | 可取消 | 已组合 | 默认操作 |
|---|---|---|---|---|---|---|---|
DOMActivate
| 同步 | 是 | 元素
| UIEvent
| 是 | 是 | 无 |
DOMFocusIn
| 同步 | 是 | Window, Element | FocusEvent
| No | 是 | 无 |
DOMFocusOut
| 同步 | 是 | Window, Element | FocusEvent
| No | 是 | 无 |
keypress
| 同步 | 是 | 元素
| KeyboardEvent
| 是 | 是 | 各异:启动文本合成系统;blur 和 focus 事件;DOMActivate 事件;其他事件 |
textInput
| 同步 | 是 | 元素
| TextEvent
| 是 | 是 | 参见定义 |
8.1. 旧版 UIEvent 事件
8.1.1. 旧版 UIEvent 事件类型
8.1.1.1. DOMActivate
| 类型 | DOMActivate
|
|---|---|
| Interface | UIEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | 是 |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
当按钮、链接或其他状态更改元素被激活时,用户代理必须分发此事件。
DOMActivate 事件类型在本规范中定义仅供参考和完整性,但本规范弃用该事件类型的使用,转而支持相关的 事件类型 click。其他规范可以定义并维护其自己的 DOMActivate 事件类型以实现向后兼容。
虽然 DOMActivate 和 click 并不完全等效,但 click 事件类型的实现行为已发展为涵盖 DOMActivate 事件类型所设计的关键无障碍访问方面,且得到更广泛的实现。建议内容创作者使用 click 事件类型而非相关的 mousedown 或 mouseup 事件类型,以确保最大的无障碍性。
支持 DOMActivate 事件类型的实现也应将 DOMActivate 事件分发为与激活触发器相关联的 click 事件的默认行为。然而,此类实现对于任何给定的激活触发器,应仅启动相关联的激活行为一次。
XForms [XFORMS11] 要求支持 DOMActivate 事件类型,该规范旨在在宿主语言中实现。如果要在不支持 DOMActivate 事件类型的本规范原生实现中安装基于插件或脚本的 XForms 实现,XForms 用户代理必须根据相应的激活触发器自行合成并分发 DOMActivate 事件。
因此,当符合 UI 事件标准的用户代理分发 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
|
|---|---|
| Interface | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
|
当事件目标接收焦点时,用户代理必须分发此事件。在分发此事件类型之前,必须将焦点赋予该元素。此事件类型必须在事件类型 focus 之后分发。
DOMFocusIn 事件类型在本规范中定义仅供参考和完整性,但本规范弃用该事件类型的使用,转而支持相关的事件类型 focus 和 focusin。
8.2.1.2. DOMFocusOut
| 类型 | DOMFocusOut
|
|---|---|
| Interface | FocusEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | Window, Element |
| 可取消 | No |
| 已组合 | 是 |
| 默认操作 | 无 |
| 上下文 (受信任事件) |
|
当事件目标失去焦点时,用户代理必须分发此事件。在分发此事件类型之前,必须从该元素移除焦点。此事件类型必须在事件类型 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
|
|---|---|
| Interface | KeyboardEvent
|
| 同步 / 异步 | 同步 |
| 冒泡 | 是 |
| 受信任的目标 | 元素
|
| 可取消 | 是 |
| 已组合 | 是 |
| 默认操作 | 各异:启动文本合成系统;blur 和 focus 事件;DOMActivate 事件;其他事件 |
| 上下文 (受信任事件) |
|
如果用户代理支持此事件,当且仅当该按键正常产生字符值时,才必须在按下按键时分发此事件。keypress 事件类型与设备相关,依赖于输入设备的功能及其在操作系统中的映射方式。
此事件类型必须在键映射之后生成。使用输入法编辑器时,不得触发此事件。
如果取消此事件,除了取消默认行为外,还应阻止 input 事件触发。
作者应使用 beforeinput 事件而非 keypress 事件。
keypress 事件传统上与检测字符值相关,而非物理按键,并且在某些配置中可能并非在所有按键上都可用。
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
有关 TextEvent 接口和 textInput 事件,请参阅 UI 事件算法中的文本事件部分。
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 提供反馈,FooCorp 随后相应地更改了 fooJump 的行为。一段时间后,另一家供应商 BarOrg
决定他们也想要该功能,但实现方式略有不同,因此他们在事件类型名称中使用了自己的供应商特定前缀 "bar":barJump。尝试此版本 jump 事件类型的内容作者使用 BarOrg 的事件类型名称注册事件。希望编写同时兼容两款浏览器的代码的内容作者可以分别用特定处理程序注册每个事件类型,或者使用相同的处理程序并根据事件类型的名称进行切换。因此,不同代码库中的早期实验不会产生冲突,早期采用者也能够为多个实现编写易于维护的代码。
最终,随着功能成熟,两款浏览器的行为都会趋于稳定,并可能由于内容作者和用户的反馈或通过正式标准化而趋同。随着这种稳定性的出现,冲突风险降低,内容作者可以删除分支代码,并使用 jump 事件类型名称(甚至在正式标准化之前),使用相同的事件处理程序和更通用的注册方法:someElement.addEventListener( "jump", doJump, false)。
9.3.1. 已知的特定于实现的前缀
截至撰写本文时,已知存在以下事件类型名称前缀:
| 前缀 | Web 引擎 | 组织机构 |
|---|---|---|
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 文档试图嵌入本地网络或 localhost 上不同端口的资源。嵌入的 DOM 应用程序随后可以监听 error 和 load 事件,以确定本地系统中哪些其他计算机是可访问的,或者系统上哪些端口是开放的,从而为进一步的攻击做准备。
仅靠 UI 事件的实现通常不足以执行此类攻击,并且可能支持此类攻击的设施的安全注意事项适用。为了符合本规范,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 Communications Corporation) 至 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 文档中,主体元素代表文档的内容。在格式良好的 HTML 文档中,主体元素是根元素的直接后代。
- 字符值 (character value)
-
在键值的上下文中,字符值是表示一个或多个 Unicode 字符的字符串,例如字母或符号,或一组字母,每个字母都属于有效的 Unicode 字符类别。在本规范中,字符值表示为 unicode 字符串(例如
U+0020)或同一码点的字形表示(例如" "),并进行颜色编码以帮助区分这两种表示形式。在源代码中,某些键值(如非图形字符)可以使用所使用编程语言的字符转义语法来表示。
- 死键 (dead key)
-
死键是一个按键或按键组合,其本身不产生字符,但与另一个键组合或顺序使用时会产生一个修改后的字符,例如带变音符号的字符(例如
"ö","é","â")。 - 默认行为 (default action)
-
默认行为是一种可选的补充行为,实现必须在与事件对象的分发相结合的情况下执行。每个事件类型定义和每个规范都定义了该事件类型的默认行为(如果有)。在某些情况下,例如当与激活触发器相关联时,事件的实例可能具有多个默认行为。可以通过调用
preventDefault()方法取消默认行为。 - 增量 (delta)
-
用户代理为响应支持
WheelEvent接口(例如鼠标滚轮或触摸板)的输入设备的物理移动而滚动或缩放页面的估计滚动量(以像素、行或页为单位)。增量 (delta) 的值(例如deltaX,deltaY或deltaZ属性)应在当前deltaMode属性的上下文中进行解释。滚轮(或其他设备)的物理移动与增量是正还是负之间的关系取决于环境和设备。然而,如果用户代理将滚动作为默认行为,则增量的符号由右手坐标系给出,其中正 X、Y 和 Z 轴分别指向文档的最右边缘、最底边缘和最远深度(远离用户)。 - 不推荐 (deprecated)
-
标记为“已弃用”的功能包含在本规范中作为对旧实现或规范的参考,但它们是可选的且不建议使用。仅应在本规范中弃用具有现有或正在进行中的替代方案的功能。不包含对该功能支持的实现可以出于与现有内容的向后兼容性的原因实现已弃用的功能,但创建内容的内容作者不应使用已弃用的功能,除非没有其他方法来解决用例。引用本规范的其他规范不应使用已弃用的功能,而应指向该功能所替代的替代方案。本规范中标记为“已弃用”的功能预计将在未来的规范中删除。
- 空字符串
-
空字符串是长度为 0 的
DOMString类型的值,即不包含任何字符(既没有打印字符也没有控制字符)的字符串。 - 事件焦点 (event focus)
-
事件焦点是对文档内特定元素或其他事件目标的接收和专注的特殊状态。每个元素在聚焦时都有不同的行为,具体取决于其功能,例如为激活做准备(如按钮或超链接)、切换状态(如复选框)、接收文本输入(如文本表单字段)或复制选定文本。有关更多详细信息,请参阅 § 3.3.3 文档焦点和焦点上下文。
- 事件焦点环 (event focus ring)
-
事件焦点环是文档内有序的事件焦点目标集合。宿主语言可以定义一种或多种确定目标顺序的方法,例如文档顺序、为每个焦点目标定义的数字索引、焦点目标之间的显式指针或不同模型的混合体。每个文档可以包含多个焦点环或条件焦点环。通常,对于文档顺序或索引焦点环,焦点会从最后一个焦点目标“环绕”回到第一个。
- 事件目标 (event target)
- 事件类型 (event type)
-
事件类型 是一个具有特定名称的事件对象,它定义了将其与其他事件类型区分开来的特定触发条件、属性和其他特征。例如,
keydown事件类型具有与blur或load事件类型不同的特征。事件类型作为事件对象上的type属性暴露。通常也松散地称为 “事件”,例如keydown事件。 - 宿主语言 (host language)
-
任何集成其他语言或 API 规范的功能,同时在规范上引用原始规范而不是重新定义这些功能的语言,并且仅以原始规范定义的方式扩展这些功能。原始规范通常仅旨在在一种或多种宿主语言的上下文中实现,而不是作为独立语言。例如,XHTML、HTML 和 SVG 是 UI 事件的宿主语言,它们集成并扩展了本规范中定义的对象和模型。
- IME
- 输入法编辑器
-
输入法编辑器 (IME),也称为 前端处理器,是一种在击键和表意文字或其他字符之间进行转换的应用程序,通常通过用户引导的字典查找,常用于东亚语言(例如中文、日文、韩文)。IME 也可用于基于字典的单词补全,例如在移动设备上。请参阅 § 4.3.3 输入法编辑器了解本规范中对 IME 的处理。另请参阅 文本合成系统。
- 键映射 (key mapping)
-
键映射是将键值分配给特定按键的过程,它是多种因素共同作用的结果,包括操作系统和键盘布局(例如 QWERTY, Dvorak, 西班牙语, InScript, 中文等),并且在考虑了所有修饰键 (
Shift,Alt等) 和死键状态之后。 - 键值 (key value)
-
键值是与特定状态下的按键相关联的字符值或多字符字符串(例如
"Enter","Tab", 或"MediaTrackNext")。每个键都有一个键值,无论它是否有字符值。这包括控制键、功能键、修饰键、死键和任何其他键。任何给定键在任何特定时间的键值取决于键映射。 - 修饰键 (modifier key)
-
修饰键会改变按键的正常行为,例如产生不同大小写的字符(如
Shift键),或更改按键触发的功能(如Fn或Alt键)。有关修饰键的更多信息,请参阅 § 4.3.1 修饰键,并参阅 [UIEvents-Key] 中 修饰键表以获取有效修饰键列表。 - 命名空间 URI
-
命名空间 URI 是标识 XML 命名空间的 URI。这在 [XML-Names11] 中称为命名空间名称。另请参阅第 1.3.2 节 DOM URI 和 1.3.3 XML 命名空间关于 DOM API 中 URI 和命名空间 URI 处理与比较的规定。
- QWERTY
-
QWERTY(发音为
ˈkwɜrti
)是一种常见的键盘布局,之所以这样命名,是因为顶行字母键上的前五个字符键是 Q、W、E、R、T 和 Y。还有许多其他流行的键盘布局(包括 Dvorak 和 Colemak 布局),大多是为本地化或人体工程学而设计的。 - 根元素
-
文档的第一个元素节点,所有其他元素都是其子节点。即文档元素。
- 文本合成系统
-
一种软件组件,它解释某种形式的替代输入(例如 输入法编辑器、语音处理器或手写识别系统)并将其转换为文本。
- Unicode 字符类别
-
为每个 Unicode 码位定义的“常规类别”值的子集。此子集包含所有字母(Ll、Lm、Lo、Lt、Lu)、数字(Nd、Nl、No)、标点(Pc、Pd、Pe、Pf、Pi、Po、Ps)和符号(Sc、Sk、Sm、So)类别值。
- 未初始化的值
-
在事件通过
initEvent()初始化之前,任何事件属性(例如bubbles或currentTarget)的值。事件的未初始化值在通过createEvent()方法创建新事件后立即适用。