1. 介绍
1.1. 概述
UI Events 设计有两个主要目标。第一个目标是设计一个 事件 系统,该系统允许注册 事件监听器, 并描述事件在树结构中的流动方式。此外,本规范将为用户界面控制和文档变更通知提供标准事件模块,并为这些事件模块定义相关的上下文信息。
UI Events 的第二个目标是提供当前主流浏览器所用事件系统的通用子集,旨在促进现有脚本和内容的互操作性。并不期望该目标能实现完全的向后兼容,但规范会在可能时予以实现。
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
| 同步 | 否 | Window, Element | Event
| 否 | 无 |
auxclick
| 同步 | 是 | Element | PointerEvent
| 是 | 视情况而定 |
beforeinput
| 同步 | 是 | Element | InputEvent
| 是 | 更新 DOM 元素 |
blur
| 同步 | 否 | Window, Element | FocusEvent
| 否 | 无 |
click
| 同步 | 是 | Element | PointerEvent
| 是 | 视情况而定:对于具有激活行为的 目标,执行 激活行为;对于可聚焦 目标,使元素获得焦点。 |
compositionstart
| 同步 | 是 | Element | CompositionEvent
| 是 | 显示 文本输入法系统候选窗口 |
compositionupdate
| 同步 | 是 | Element | CompositionEvent
| 否 | 无 |
compositionend
| 同步 | 是 | Element | CompositionEvent
| 否 | 无 |
contextmenu
| 同步 | 是 | Element | PointerEvent
| 是 | 如支持则调用上下文菜单 |
dblclick
| 同步 | 是 | Element | MouseEvent
| 否 | 视情况而定:对于具有激活行为的 目标,执行 激活行为;对于可聚焦 目标,使元素获得焦点。 |
error
| 异步 | 否 | Window, Element | Event
| 否 | 无 |
focus
| 同步 | 否 | Window, Element | FocusEvent
| 否 | 无 |
focusin
| 同步 | 是 | Window, Element | FocusEvent
| 否 | 无 |
focusout
| 同步 | 是 | Window, Element | FocusEvent
| 否 | 无 |
input
| 同步 | 是 | Element | InputEvent
| 否 | 无 |
keydown
| 同步 | 是 | Element | KeyboardEvent
| 是 | 视情况而定:触发 beforeinput 和 input 事件;启动 文本输入法系统;blur 和 focus 事件;keypress
事件(如支持);激活行为;其他事件
|
keyup
| 同步 | 是 | Element | KeyboardEvent
| 是 | 无 |
load
| 异步 | 否 | Window, Document, Element | Event
| 否 | 无 |
mousedown
| 同步 | 是 | Element | MouseEvent
| 是 | 视情况而定:开始拖拽/放置操作;开始文本选择;开始滚动/平移交互(中键配合时,如支持) |
mouseenter
| 同步 | 否 | Element | MouseEvent
| 否 | 无 |
mouseleave
| 同步 | 否 | Element | MouseEvent
| 否 | 无 |
mousemove
| 同步 | 是 | Element | MouseEvent
| 是 | 无 |
mouseout
| 同步 | 是 | Element | MouseEvent
| 是 | 无 |
mouseover
| 同步 | 是 | Element | MouseEvent
| 是 | 无 |
mouseup
| 同步 | 是 | Element | MouseEvent
| 是 | 无 |
select
| 同步 | 是 | Element | Event
| 否 | 无 |
unload
| 同步 | 否 | Window, Document, Element | Event
| 否 | 无 |
wheel
| 异步 | 是 | Element | WheelEvent
| 是 | 滚动(或缩放)文档 |
关于本规范中弃用事件列表,请见文末附录旧版事件类型。
以下是对上表的一种解读方式:load
事件会在 Element
节点的捕获和目标阶段触发为该事件注册的 事件监听器。该事件不可取消。如果为 load
事件在 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,要初始化的
UIEvent
eventType,包含事件类型的 DOMString
eventTarget,事件的
EventTarget
bubbles,如果该事件可冒泡则为 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. 鼠标事件
鼠标事件模块起源于 [HTML401]
的 onclick
、ondblclick
、
onmousedown
、onmouseup
、onmouseover
、onmousemove
、
onmouseout
属性。此事件模块专为指针输入设备(如鼠标或轨迹球)设计。
3.4.1. MouseEvent 接口
在 DOM Level 2 中引入,本规范中有所修改
MouseEvent
接口提供了与鼠标事件相关的特定上下文信息。
在嵌套元素的情况下,鼠标事件总是针对最深层嵌套的元素。
目标元素的祖先可以通过事件冒泡获取其后代元素内发生的鼠标事件通知。
要创建 MouseEvent
接口实例,可使用 MouseEvent
构造函数,并传递可选的 MouseEventInit
字典。
使用 MouseEvent
的 initMouseEvent
初始化对象时,实现可利用 clientX
和 clientY
计算其他坐标(如 DOM Level 0 或其它专有属性暴露的目标坐标,例如 pageX
)。
3.4.1.1. MouseEvent
[Exposed =Window ]interface :
MouseEvent UIEvent {(
constructor DOMString ,
type optional MouseEventInit = {});
eventInitDict readonly attribute long screenX ;readonly attribute long screenY ;readonly attribute long clientX ;readonly attribute long clientY ;readonly attribute long layerX ;readonly attribute long layerY ;readonly attribute boolean ctrlKey ;readonly attribute boolean shiftKey ;readonly attribute boolean altKey ;readonly attribute boolean metaKey ;readonly attribute short button ;readonly attribute unsigned short buttons ;readonly attribute EventTarget ?relatedTarget ;boolean getModifierState (DOMString ); };
keyArg
screenX
, 类型为 long, 只读-
事件发生时相对于屏幕坐标原点的水平坐标。
该属性的 未初始化值必须为
0
。 screenY
, 类型为 long, 只读-
事件发生时相对于屏幕坐标原点的垂直坐标。
该属性的 未初始化值必须为
0
。 clientX
, 类型为 long, 只读-
事件发生时相对于事件关联的视口的水平坐标。
该属性的 未初始化值必须为
0
。 clientY
, 类型为 long, 只读-
事件发生时相对于事件关联的视口的垂直坐标。
该属性的 未初始化值必须为
0
。 layerX
, 类型为 long, 只读-
距离最近的 祖先
元素的水平偏移,
该祖先元素是 堆叠上下文、定位元素,
或在 绘制堆叠上下文的定位阶段绘制。
该属性的 未初始化值必须为
0
。 layerY
, 类型为 long, 只读-
距离最近的 祖先
元素的垂直偏移,
该祖先元素是 堆叠上下文、定位元素,
或在 绘制堆叠上下文的定位阶段绘制。
该属性的 未初始化值必须为
0
。 ctrlKey
, 类型为 boolean, 只读-
参见
KeyboardEvent
的ctrlKey
属性。该属性的 未初始化值必须为
false
。 shiftKey
, 类型为 boolean, 只读-
参见
KeyboardEvent
的shiftKey
属性。该属性的 未初始化值必须为
false
。 altKey
, 类型为 boolean, 只读-
参见
KeyboardEvent
的altKey
属性。该属性的 未初始化值必须为
false
。 metaKey
, 类型为 boolean, 只读-
参见
KeyboardEvent
的metaKey
属性。该属性的 未初始化值必须为
false
。 button
, 类型为 short, 只读-
鼠标事件由鼠标按钮按下或释放引发时,
button
必须用于指示哪个指针设备按钮状态发生了变化。button
属性的值必须如下:-
0
表示设备主按钮(一般为左键,或单键设备上的唯一按钮,用于激活控件或选择文本)或未初始化值。 -
1
表示辅助按钮(一般为中键,常与鼠标滚轮结合使用)。 -
2
表示次级按钮(一般为右键,常用于显示上下文菜单)。 -
3
表示 X1(后退)按钮。 -
4
表示 X2(前进)按钮。
部分指针设备提供或模拟更多按钮状态,超过
2
或小于0
的值可表示这些按钮。button
的值不会在非由鼠标按钮按下/释放引发的事件中更新,此时请勿将0
解释为左键,而应视为未初始化值。某些与
mousedown
、mouseup
等事件相关的 默认行为 依赖于具体鼠标按钮。该属性的 未初始化值必须为
0
。 -
buttons
, 类型为 unsigned short, 只读-
在任何鼠标事件中,
buttons
必须用于指示当前被按下的鼠标按钮组合,以位掩码表示。虽然名称类似,
buttons
与button
的值完全不同。button
在mousedown
/mouseup
事件处理期间为有效值,buttons
属性则反映任意可信MouseEvent
对象的鼠标按钮状态(分发期间),包括“无按钮激活”状态(0)。buttons
属性值必须如下:-
0
表示当前无按钮激活。 -
1
表示设备主按钮(一般为左键,或单键设备上的唯一按钮,用于激活控件或选择文本)。 -
2
表示次级按钮(一般为右键,常用于显示上下文菜单,如有)。 -
4
表示辅助按钮(一般为中键,常与鼠标滚轮结合使用)。
部分指针设备提供或模拟更多按钮。要表示这些按钮,值需依次加倍(二进制序列
8
、16
、32
、...)。任意按钮值组合之和唯一,内容作者可用位操作判断当前被按下的按钮数及具体按钮,适用于任意数量的鼠标按钮。例如
3
表示左键和右键同时按下,5
表示左键和中键同时按下。某些与
mousedown
、mouseup
等事件相关的 默认行为 依赖于具体鼠标按钮。该属性的 未初始化值必须为
0
。 -
relatedTarget
, 类型为 EventTarget, 只读, 可为 null-
用于标识与 UI 事件相关的次级
EventTarget
,具体取决于事件类型。该属性的 未初始化值必须为
null
。 getModifierState(keyArg)
-
本规范中引入
使用按键值查询修饰键状态。
如果为修饰键且已激活则返回
true
,否则返回false
。- DOMString keyArg
- 参见
KeyboardEvent
的getModifierState()
方法参数说明。
3.4.1.2. MouseEventInit
dictionary :
MouseEventInit EventModifierInit {long screenX = 0;long screenY = 0;long clientX = 0;long clientY = 0;short button = 0;unsigned short buttons = 0;EventTarget ?relatedTarget =null ; };
screenX
, 类型为 long,默认值为0
-
初始化
screenX
属性为鼠标指针在用户屏幕上的期望水平相对位置。将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。
screenY
, 类型为 long,默认值为0
-
初始化
screenY
属性为鼠标指针在用户屏幕上的期望垂直相对位置。将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。
clientX
, 类型为 long,默认值为0
-
初始化
clientX
属性为鼠标指针在用户浏览器客户端窗口的期望水平位置。将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。
clientY
, 类型为 long,默认值为0
-
初始化
clientY
属性为鼠标指针在用户浏览器客户端窗口的期望垂直位置。将事件对象初始化为给定鼠标位置时,不应移动用户的鼠标指针到该初始化位置。
button
, 类型为 short,默认值为0
-
初始化
button
属性为鼠标按钮的期望状态所对应的数字。数值 0 代表主鼠标按钮,1 代表辅助/中间按钮,2 代表右键。大于 2 的数字也可能出现,但本文档未作规定。
buttons
, 类型为 unsigned short,默认值为0
-
初始化
buttons
属性为一个数字,表示要视为激活状态的一个或多个鼠标按钮。buttons
属性为位字段,掩码值为 1 时表示主按钮按下,2 时表示右键按下,4 时表示辅助/中键按下。在 JavaScript 中,如需初始化
buttons
属性为右键(2)和中键(4)同时按下,可赋值为:
{ buttons: 2 | 4 }
或
{ buttons: 6 }
relatedTarget
, 类型为 EventTarget,可为 null,默认值为null
-
relatedTarget
应初始化为鼠标指针刚离开的元素(对于 mouseover 或 mouseenter 事件),或鼠标指针即将进入的元素(对于 mouseout、 mouseleave 或 focusout 事件)。其他事件无需赋值(默认即为 null)。
实现在生成鼠标事件时必须维护 当前点击计数,其必须为非负整数,表示在特定时间内指针设备按钮的连续点击次数。计数重置的延迟取决于环境配置。
3.4.2. 事件修饰符初始化器
MouseEvent
和
KeyboardEvent
接口共享一组键盘修饰符属性,并支持检索额外修饰符状态的机制。下述字典允许作者初始化 MouseEvent
和
KeyboardEvent
接口的键盘修饰符属性,以及通过 getModifierState()
查询的其他修饰符状态。
使用该字典构造事件的步骤定义在 MouseEvent 构造器小节。
dictionary :
EventModifierInit UIEventInit {boolean ctrlKey =false ;boolean shiftKey =false ;boolean altKey =false ;boolean metaKey =false ;boolean modifierAltGraph =false ;boolean modifierCapsLock =false ;boolean modifierFn =false ;boolean modifierFnLock =false ;boolean modifierHyper =false ;boolean modifierNumLock =false ;boolean modifierScrollLock =false ;boolean modifierSuper =false ;boolean modifierSymbol =false ;boolean modifierSymbolLock =false ; };
ctrlKey
, 类型为 boolean,默认值为false
-
初始化
ctrlKey
属性为MouseEvent
或KeyboardEvent
对象,如果Control
键修饰符应视为激活则为true
,否则为false
。为
true
时,实现还必须初始化事件对象的键修饰状态,使得调用getModifierState()
或getModifierState()
并传入参数Control
时返回true
。 shiftKey
, 类型为 boolean,默认值为false
-
初始化
shiftKey
属性为MouseEvent
或KeyboardEvent
对象,如果Shift
键修饰符应视为激活则为true
,否则为false
。为
true
时,实现还必须初始化事件对象的键修饰状态,使得调用getModifierState()
或getModifierState()
并传入参数Shift
时返回true
。 altKey
, 类型为 boolean,默认值为false
-
初始化
altKey
属性为MouseEvent
或KeyboardEvent
对象,如果Alt
(备用)键(或Option
)修饰符应视为激活则为true
,否则为false
。为
true
时,实现还必须初始化事件对象的键修饰状态,使得调用getModifierState()
或getModifierState()
并传入参数Alt
时返回true
。 metaKey
, 类型为 boolean,默认值为false
-
初始化
metaKey
属性为MouseEvent
或KeyboardEvent
对象,如果Meta
键修饰符应视为激活则为true
,否则为false
。为
true
时,实现还必须初始化事件对象的键修饰状态,使得调用getModifierState()
或getModifierState()
并传入参数Meta
时返回true
。 modifierAltGraph
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数AltGraph
时返回true
。 modifierCapsLock
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数CapsLock
时返回true
。 modifierFn
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数Fn
时返回true
。 modifierFnLock
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数FnLock
时返回true
。 modifierHyper
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数Hyper
时返回true
。 modifierNumLock
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数NumLock
时返回true
。 modifierScrollLock
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数ScrollLock
时返回true
。 modifierSuper
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数Super
时返回true
。 modifierSymbol
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数Symbol
时返回true
。 modifierSymbolLock
, 类型为 boolean,默认值为false
- 初始化事件对象的键修饰状态,使得调用
getModifierState()
或getModifierState()
并传入参数SymbolLock
时返回true
。
3.4.2.1. 构造 MouseEvent
通常,当调用 Event
接口或其继承自 Event
接口的构造函数时,应遵循 [DOM] 中描述的步骤。然而
MouseEvent
接口提供了用于初始化 Event
对象键盘修饰符内部状态的额外字典成员,这些状态可通过 getModifierState()
方法查询。本节补充了 DOM4 中初始化新 MouseEvent
对象的相关步骤,以支持这些可选修饰符状态。
在构造 MouseEvent
或使用下述算法从这些对象派生对象时,所有 MouseEvent
及其派生对象都具有可通过 键盘修饰符名称(参见 修饰键列表,[UIEvents-Key])设置和获取的
内部键修饰符状态。
以下步骤补充了 DOM4 事件构造算法:
-
如果正在构造的
Event
是MouseEvent
对象或其派生对象,且构造函数传入了EventModifierInit
参数,则执行以下子步骤:-
对每个
EventModifierInit
参数,如果字典成员以"modifier"
开头,则将字典成员名称去掉前缀"modifier"
得到 修饰键名称,并将Event
对象中匹配的 内部键修饰符状态设置为对应值。
-
3.4.3. MouseEvent 算法
3.4.3.1. 原生操作系统要求
本节的算法假定原生平台操作系统会提供如下能力:
-
鼠标移动时触发事件(由 处理原生鼠标移动 处理)
-
鼠标按钮按下时触发事件(由 处理原生鼠标按下 处理)
-
鼠标按钮释放时触发事件(由 处理原生鼠标释放 处理)
-
识别鼠标按钮按下是否应被解释为“点击”(由 处理原生鼠标点击 处理)
-
例如通过标志位或单独事件识别
-
如果单独的“点击”事件被触发,则原生操作系统会在对应的“鼠标释放”事件之后立即触发该事件,中间不会有其他鼠标相关事件
-
-
识别鼠标点击是否为“双击”(由 处理原生鼠标双击 处理)
对于上述事件,操作系统能提供如下信息:
-
相对于原生操作系统桌面的鼠标 x、y 坐标
-
相对于 UA(用户代理)窗口视口的鼠标 x、y 坐标
-
当前按下了哪些键盘修饰键
3.4.3.2. MouseEvent 全局状态
3.4.3.2.1. 用户代理级状态
UA 必须维护如下全局共享值:
用于追踪鼠标按钮当前状态的 鼠标按钮位掩码。
3.4.3.2.2. 窗口级状态
UA 必须维护如下窗口级共享值:
初始值为未定义的 上次鼠标元素,用于记录最近发送 MouseEvent 的 Element
。
初始为空的 上次鼠标 DOM
路径,包含最近一次发送鼠标事件时 上次鼠标元素 的所有祖先 Element
的快照。
3.4.3.3. MouseEvent 内部状态
MouseEvent
有如下内部标志用于追踪各种修饰键状态:shift
标志、control
标志、
alt 标志、altgraph 标志、
meta 标志。
如果对应修饰键在鼠标事件发生时被按下,则这些标志会被设置。
3.4.3.4. 初始化 MouseEvent
- 输入
-
event,要初始化的
MouseEvent
eventType,包含事件类型的 DOMString
eventTarget,事件的
EventTarget
bubbles,如果事件可冒泡则为 true
cancelable,如果事件可取消则为 true
- 输出
-
无
-
使用 初始化 UIEvent,参数为 event、eventType、eventTarget、bubbles、cancelable
-
初始化以下公开属性:
-
使用 初始化 MouseEvent 的 PointerLock 属性,参数为 event
3.4.3.5. 设置鼠标事件修饰符
- 输入
-
event,要更新的
MouseEvent
- 输出
-
无
-
如果 键修饰符状态 包含 "Control",则设置 event 的 control 标志,否则取消设置
-
如果 键修饰符状态 包含 "AltGraph",则设置 event 的 altgraph 标志,否则取消设置
-
如果 control 标志 被设置,则 event.
ctrlKey
= true,否则为 false -
如果 alt 标志 或 altgraph 标志 被设置,则 event.
altKey
= true,否则为 false
3.4.3.6. 创建可取消的 MouseEvent
- 输入
-
eventType,包含有效
MouseEvent
类型的 DOMStringeventTarget,事件的
EventTarget
- 输出
-
无
-
令 bubbles 为 "true"
-
令 cancelable 为 "true"
-
令 event = 使用
MouseEvent
创建新事件 的结果 -
使用 初始化 MouseEvent,参数为 event、eventType、eventTarget、bubbles、cancelable
-
返回 event
3.4.3.7. 创建不可取消的 MouseEvent
- 输入
-
eventType,包含有效
MouseEvent
类型的 DOMStringeventTarget,事件的
EventTarget
- 输出
-
无
-
令 bubbles 为 "false"
-
令 cancelable 为 "false"
-
令 event = 使用
MouseEvent
创建新事件 的结果 -
使用 初始化 MouseEvent,参数为 event、eventType、eventTarget、bubbles、cancelable
-
返回 event
3.4.3.8. 计算 MouseEvent button 属性
- 输入
-
mbutton,用于识别鼠标按钮的 ID
- 输出
-
适用于存储在
MouseEvent
的button
属性的按钮 ID
-
如果 mbutton 是主鼠标按钮,则返回 0
-
如果 mbutton 是辅助(中间)鼠标按钮,则返回 1
-
如果 mbutton 是次级鼠标按钮,则返回 2
-
如果 mbutton 是 X1(后退)按钮,则返回 3
-
如果 mbutton 是 X2(前进)按钮,则返回 4
3.4.3.9. 根据原生事件设置 MouseEvent 属性
- 输入
-
event,要初始化的
MouseEvent
native,原生鼠标事件
- 输出
-
无
TODO
-
如果 event.
type
是 [ mousedown, mouseup ] 之一,则-
令 mbutton 为 native 中用于识别按下鼠标按钮的 ID
-
设置 event.
button
= 计算 MouseEvent button 属性,参数为 mbutton
-
3.4.3.10. 处理原生鼠标按下
- 输入
-
native,原生 mousedown
- 输出
-
无
-
令 mbutton 为 native 中用于识别按下鼠标按钮的 ID
-
按如下方式更新 鼠标按钮位掩码:
-
如果 mbutton 是主鼠标按钮,则设置 0x01 位
-
如果 mbutton 是次级鼠标按钮,则设置 0x02 位
-
如果 mbutton 是辅助(中间)鼠标按钮,则设置 0x04 位
其它按钮可从 0x08 开始添加
-
-
令 target = 命中测试,参数为 native 的视口相关坐标
-
令 event = 创建可取消的 MouseEvent,参数为 "mousedown"、target
-
根据原生事件设置 MouseEvent 属性,参数为 native
-
可能发送 pointerdown 事件,参数为 event
-
令 result = 在 target 处分发 event
-
如果 result 为 true 且 target 是 可聚焦区域 且为 可点击聚焦,则
-
在 target 运行 聚焦步骤
-
-
如果 mbutton 是次级鼠标按钮,则
-
可能显示上下文菜单,参数为 native、target
-
3.4.3.11. 处理原生鼠标释放
- 输入
-
native,原生 mouseup
- 输出
-
无
在 mousedown 和 mouseup 之间可能发生其他鼠标事件。
-
令 mbutton 为 native 中用于识别按下鼠标按钮的 ID
-
按如下方式更新 鼠标按钮位掩码:
-
如果 mbutton 是主鼠标按钮,则清除 0x01 位
-
如果 mbutton 是次级鼠标按钮,则清除 0x02 位
-
如果 mbutton 是辅助(中间)鼠标按钮,则清除 0x04 位
-
-
令 target = 命中测试,参数为 native 的视口相关坐标
-
令 event = 创建可取消的 MouseEvent,参数为 "mouseup"、target
-
根据原生事件设置 MouseEvent 属性,参数为 native
-
可能发送 pointerup 事件,参数为 event
-
在 target 派发 event
3.4.3.13. 发送点击事件
- 输入
-
native,原生 mousedown
target,事件的
EventTarget
- 输出
-
无
-
令 mbutton = 1(默认主鼠标按钮)
-
如果 native 有效,则
-
令 mbutton 为 native 中用于识别按下鼠标按钮的 ID
-
-
如果 mbutton 是主鼠标按钮,则 eventType 为 "click",否则为 "auxclick"
-
令 event = 创建 PointerEvent,参数为 eventType、target
-
如果 native 有效,则
-
根据原生事件设置 MouseEvent 属性,参数为 event、native
-
如果 event.
screenX
不是整数,则取整 -
如果 event.
screenY
不是整数,则取整
-
-
在 target 派发 event
参见 pointerevents/100,了解浏览器使用 PointerEvents 及坐标取整的信息。
任何“默认行为”在分发时通过触发目标的 激活行为 算法处理,因此无需在此处理。但需确认现有规范是否处理了 disabled/css-pointer-events/inert/...
要处理 `HTMLelement.click()`,调用本算法时 native = null,target = `HTMLelement`。
要处理键盘触发的点击,调用本算法时 native = null,target = 当前聚焦元素。
3.4.3.14. 处理原生鼠标双击
- 输入
-
native,原生鼠标双击事件
- 输出
-
无
本算法应在处理原生鼠标点击后立即调用,用于生成双击事件。
-
令 mbutton 为 native 中用于识别按下鼠标按钮的 ID
-
如果 mbutton 不是主鼠标按钮,则返回
-
令 target = 命中测试,参数为 native 的视口相关坐标
-
令 event = 创建 PointerEvent,参数为 "dblclick"、target
-
根据原生事件设置 MouseEvent 属性,参数为 event、native
-
如果 event.
screenX
不是整数,则取整 -
如果 event.
screenY
不是整数,则取整 -
在 target 派发 event
3.4.3.15. 处理原生鼠标移动
- 输入
-
native,原生鼠标移动事件
- 输出
-
无
本算法假设 PointerEvents 分发方式,当前规范未明确定义。待 pointerevents/285 解决后可能需更新。
-
令 target = 命中测试,参数为 native 的视口相关坐标
-
令 targetDomPath = 计算 DOM 路径
-
为离开当前元素生成事件:
-
如果 上次鼠标元素 已定义且不等于 target,则
-
令 mouseout = 创建可取消的 MouseEvent,参数为 "mouseout"、上次鼠标元素
TODO:用 native 设置 mouseout 属性,含 CSSOM 属性
-
可能发送 pointerout 事件,参数为 mouseout
-
在 target 派发 mouseout
验证取消后行为(似乎无影响)。
-
令 leaveElements 为 上次鼠标 DOM 路径 的拷贝,去除与 targetDomPath 共有元素。
-
遍历 leaveElements 中每个 element
处理 element 被删除或移动的情况。DOM 变化是否应触发 mouseleave?现在是否发送?是否应丢弃?需验证主流浏览器行为。
-
令 mouseleave = 创建不可取消的 MouseEvent,参数为 "mouseleave"、element
-
设置 mouseleave.
composed
= false检查兼容性:event.composed 的值。规范为 false。Chrome/Linux = true,Firefox/Linux = false。
-
可能发送 pointerleave 事件,参数为 mouseleave
-
令 result = 在 element 派发 mouseleave
-
-
-
-
为进入新元素生成事件:
-
如果 target 不等于 上次鼠标元素,则
-
令 mouseover = 创建可取消的 MouseEvent,参数为 "mouseover"、target
TODO:用 native 设置 mouseout 属性,含 CSSOM 属性
-
可能派发 pointerover 事件,使用 mouseover
-
在 target 派发 mouseout
需要验证被取消时的行为(似乎没有影响)。
-
令 enterElements 为 targetDomPath 的副本,去除所有与最近鼠标 DOM 路径相同的元素。
-
对于 enterElements 中的每个 element,执行
处理 element 被删除或移动的情况。
-
令 mouseenter = 创建不可取消的 MouseEvent,类型为 "mouseenter",目标为 element
-
设置 mouseenter.
composed
= false兼容性检查:event.composed 的值。规范为 false。 Chrome/Linux = true。 Firefox/Linux = false。
-
可能派发 pointerenter 事件,使用 mouseenter
检查 shadow DOM 元素的兼容性。 Chrome/Linux 会在元素和 shadow root 都触发此事件。
-
令 result = 在 element 派发 mouseenter
-
-
设置最近鼠标元素为 target
-
设置最近鼠标 DOM 路径为 targetDomPath
-
-
-
令 mousemove = 创建可取消的 MouseEvent,类型为 "mousemove",目标为 element
-
可能派发 pointermove 事件,使用 mousemove
-
在 element 派发 mousemove
3.4.3.16. 可能显示上下文菜单
- 输入
-
native,原生 mousedown 或 pointer 事件
target,事件的
EventTarget
- 输出
-
无
-
令 menuevent = 创建一个 PointerEvent,类型为 "contextmenu",目标为 target
-
如果 native 有效,则
-
根据 native 设置 MouseEvent 属性 ,使用 native
-
-
令 result = 在 target 派发 menuevent
-
如果 result 为 true,则显示 UA 上下文菜单
-
处理键盘触发的上下文菜单时,调用本算法 native = null,target = 当前聚焦元素。
3.4.4. 鼠标事件顺序
本规范定义的某些鼠标事件必须以特定顺序发生。下表展示了当指针设备的光标移入某元素时必须发生的事件序列:
事件类型 | 元素 | 备注 | |
---|---|---|---|
1 | mousemove
| ||
指针设备移动到元素A内…… | |||
2 | mouseover
| A | |
3 | mouseenter
| A | |
4 | mousemove
| A | 多次 mousemove
事件
|
指针设备移出元素A…… | |||
5 | mouseout
| A | |
6 | mouseleave
| A |
当指针设备进入元素 A,再进入嵌套的元素 B,再移出时,必须依次发生以下事件:
事件类型 | 元素 | 备注 | |
---|---|---|---|
1 | mousemove
| ||
指针设备移入元素A…… | |||
2 | mouseover
| A | |
3 | mouseenter
| A | |
4 | mousemove
| A | 多次 mousemove
事件
|
指针设备移入嵌套元素B…… | |||
5 | mouseout
| A | |
6 | mouseover
| B | |
7 | mouseenter
| B | |
8 | mousemove
| B | 多次 mousemove
事件
|
指针设备从元素B移回A…… | |||
9 | mouseout
| B | |
10 | mouseleave
| B | |
11 | mouseover
| A | |
12 | mousemove
| A | 多次 mousemove
事件
|
指针设备移出元素A…… | |||
13 | mouseout
| A | |
14 | mouseleave
| A |
有时元素可以通过CSS设置视觉重叠。如下例,A、B、C三个元素在页面上尺寸和绝对位置完全重合,C是B的子元素,B是A的子元素:
当指针设备从堆叠外部移入标记为C的最顶层元素后再移出,必须按以下事件序列发生:
事件类型 | 元素 | 备注 | |
---|---|---|---|
1 | mousemove
| ||
指针设备移入堆叠最顶层元素C | |||
2 | mouseover
| C | |
3 | mouseenter
| A | |
4 | mouseenter
| B | |
5 | mouseenter
| C | |
6 | mousemove
| C | 多次 mousemove
事件
|
指针设备移出元素C…… | |||
7 | mouseout
| C | |
8 | mouseleave
| C | |
9 | mouseleave
| B | |
10 | mouseleave
| A |
mouseover
/mouseout
事件仅触发一次,而 mouseenter
/mouseleave
事件会触发三次(分别针对每个元素)。
指针设备(如鼠标或触控板)上的按钮在某元素上按下与释放时,典型的事件顺序如下:
事件类型 | 备注 | |
---|---|---|
1 | mousedown
| |
2 | mousemove
| 可选,多次事件,有一定限制 |
3 | mouseup
| |
4 | click
| |
5 | mousemove
| 可选,多次事件,有一定限制 |
6 | mousedown
| |
7 | mousemove
| 可选,多次事件,有一定限制 |
8 | mouseup
| |
9 | click
| |
10 | dblclick
|
在 mousedown
与 mouseup
事件之间允许的 mousemove
事件的延迟、幅度、距离和数量由实现、设备和平台决定。这种容差有助于手部不稳等身体障碍用户更好地操作指针设备。
每个实现会自行决定合适的滞后容差,但一般情况下,当相关的mousedown
和mouseup
事件的事件目标为同一元素,且中间没有mouseout
或mouseleave
事件时,应该触发click
和dblclick
事件;而当相关的mousedown
和
mouseup
事件目标不同,则应该在最近的共同包含祖先元素上触发click
和dblclick
事件。
如果 mousedown
事件目标是HTML文档的
body 元素,而对应的 mouseup
事件目标是 根元素,则 click
事件会在 根元素 上分发,因为它是最近的公共包含祖先。
如果 事件目标(例如目标元素)在鼠标事件序列期间被从DOM中移除,则剩余事件不得在该元素上触发。
如果目标元素在 mousedown
事件后被移除,则不会在该元素上分发 mouseup
、click
或 dblclick
,也不会有默认激活事件。但 mouseup
事件仍会在移除后暴露给鼠标的元素上分发。同理,如果目标元素在 mouseup
事件分发期间被移除,则 click
及后续事件不会分发。
3.4.5. 鼠标事件类型
鼠标事件类型如下所列。在嵌套元素的情况下,鼠标事件类型总是会以最深层嵌套的元素为目标。目标元素的祖先可以通过冒泡机制获取其后代元素内发生的鼠标事件通知。
3.4.5.1. auxclick
类型 | auxclick
|
---|---|
接口 | PointerEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 视情况而定 |
上下文 (可信事件) |
|
auxclick
事件类型必须在指针指向的最顶层事件目标上分发,当用户按下并释放非主指针按钮,或以模拟该操作的方式激活指针时。鼠标按钮的激活方式取决于指针设备和环境配置,例如可能依赖于屏幕位置或按下与释放之间的延迟。
auxclick
事件仅应针对非主指针按钮触发(即
button
值不为 0
,buttons
值大于 1
)。主按钮(如标准鼠标左键)不得触发 auxclick
事件。相关主按钮事件请参见 click
。
auxclick
事件在同一元素上可能会被 mousedown
和
mouseup
事件先于其分发,忽略节点类型变化(如文本节点)。根据环境配置,auxclick
事件在指针按钮按下与释放之间,若发生 mouseover
、mousemove
或 mouseout
类型之一或多个事件,也可能会分发。
auxclick
事件类型的默认行为依赖于事件的事件目标以及 button
或 buttons
属性的值。典型的默认行为如下:
处理中键 auxclick
事件。
myLink.addEventListener("auxclick", function(e) {
if (e.button === 1) {
// 这将阻止默认行为,比如中键点击链接时打开新标签页。
e.preventDefault();
// 在此处处理中键点击,比如自定义打开链接或按钮到新标签页,或做其它操作。
// 例如标签栏的关闭操作等也可在这里做。
}
});
右键情况下,auxclick
事件在 contextmenu
事件之后分发。注意有些用户代理在显示上下文菜单时会屏蔽所有输入事件,因此 auxclick
在此场景下可能不可用。更多说明参见 此示例。
处理右键 auxclick 事件
myDiv.addEventListener("contextmenu", function(e) {
// 阻止显示默认上下文菜单,保证页面能收到事件。
e.preventDefault();
});
myDiv.addEventListener("auxclick", function(e) {
if (e.button === 2) {
// 在此处处理右键点击,比如弹出自定义上下文菜单。
}
});
3.4.5.2. click
类型 | click
|
---|---|
接口 | PointerEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 视情况而定 |
上下文 (可信事件) |
|
click
事件类型必须在指针指向的最顶层事件目标上分发,当用户按下并释放主指针按钮,或以模拟该操作的方式激活指针时。鼠标按钮的激活方式取决于指针设备和环境配置,例如可能依赖于屏幕位置或按下与释放之间的延迟。
click
事件只应针对主指针按钮触发(即 button
值为 0
,buttons
值为 1
)。次级按钮(如标准鼠标的中键或右键)不得触发 click
事件。相关非主按钮事件请参见 auxclick
。
click
事件可能会被 mousedown
和 mouseup
事件先于其分发,忽略节点类型变化(如文本节点)。根据环境配置,click
事件在指针按钮按下与释放之间发生 mouseover
、mousemove
或 mouseout
类型之一或多个事件时,也可能会分发。click
事件之后也可能会跟随 dblclick
事件。
如果用户在一个设置了较大
line-height 的 <p>
元素的文本节点上按下鼠标,然后略微移动鼠标使指针不再位于文本节点但仍在该 <p>
元素的块内(即指针在相同行块间但未在文本节点本身上),随后松开鼠标,则仍会触发 click
事件(只要在正常的 迟滞范围内),因为用户始终在同一元素范围内。注意 UA 生成的鼠标事件不会分发到文本节点。
除了与指针设备相关,click
事件类型还必须作为元素激活的一部分进行分发。
为最大化可访问性,内容作者建议在自定义控件定义激活行为时优先使用 click
事件类型,而不是 mousedown
或 mouseup
等更依赖设备的事件。尽管 click
事件类型起源于指针设备(如鼠标),但后续实现已扩展其为设备无关的元素激活事件类型。
click
事件类型的默认行为依赖于事件的事件目标以及 button
或 buttons
属性的值。典型的默认行为如下:
3.4.5.3. contextmenu
类型 | contextmenu
|
---|---|
接口 | PointerEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 如果支持则调用上下文菜单。 |
上下文 (可信事件) |
|
用户代理必须在调用上下文菜单前分发此事件。
当 contextmenu
事件由鼠标右键触发时,contextmenu
事件必须在 mousedown
事件后分发。
根据平台不同,contextmenu
事件可能在 mouseup
事件之前或之后分发。
3.4.5.4. 双击(dblclick)
类型 | dblclick
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
当指针设备的主按钮在某个元素上被点击两次时,用户代理必须分派此事件。
双击的定义取决于环境配置,但事件目标在 mousedown
、mouseup
和 dblclick
之间必须相同。
如果单击和双击同时发生,则此事件类型必须在事件类型 click
之后分派,否则在事件类型 mouseup
之后分派。
与 click
事件类似,dblclick
事件只应为主指针按钮触发。
次要按钮不得触发 dblclick
事件。
取消 click
事件不会影响 dblclick
事件的触发。
与 click
事件类型一样,默认行为会根据事件的 事件目标 和 button
或 buttons
属性的值而变化。dblclick
事件类型的典型默认行为与 click
事件类型一致。
3.4.5.5. mousedown
类型 | mousedown
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 视情况而定:开始拖放操作;开始文本选择;开始滚动/平移交互(若支持与中键配合) |
上下文 (可信事件) |
|
用户代理必须在指针设备按钮在某元素上按下时分发此事件。
许多实现会使用 mousedown
事件开始多种依赖上下文的默认行为。如果此事件被取消,这些默认行为可以被阻止。这些默认行为包括:开始对图片或链接进行拖放交互、开始文本选择等。同时,部分实现支持鼠标驱动的平移功能,在
mousedown
事件分发时按下中键可激活此功能。
3.4.5.6. mouseenter
类型 | mouseenter
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 否 |
可信目标 | Element
|
可取消 | 否 |
可组合 | 否 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在指针设备进入某元素或其后代元素边界时分发此事件。用户代理还必须在元素或其后代移到主指针设备下方时分发此事件。此事件类型类似于 mouseover
,但它不会冒泡,且指针设备从元素进入其后代元素边界时不得分发。
此事件类型与 CSS :hover
伪类有相似之处。另请参阅 mouseleave
事件类型。
3.4.5.7. mouseleave
类型 | mouseleave
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 否 |
可信目标 | Element
|
可取消 | 否 |
可组合 | 否 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在指针设备离开某元素及其所有后代元素边界时分发此事件。用户代理还必须在元素或其后代不再位于主指针设备下方时分发此事件。此事件类型类似于 mouseout
,但它不会冒泡,且只有指针设备离开元素及其所有子元素边界时才分发。
此事件类型与 CSS :hover
伪类有相似之处。另请参阅 mouseenter
事件类型。
3.4.5.8. mousemove
类型 | mousemove
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在指针设备位于某元素上移动时分发此事件。指针设备移动时事件的触发频率依赖于实现、设备和平台,但对于持续的指针设备移动,应连续触发多个
mousemove
事件,而不是每次鼠标移动只触发一个事件。鼓励实现根据响应性与性能平衡确定最佳事件频率。
在某些实现环境(如浏览器)中,当用户开始拖动操作(如按下鼠标按钮)并且指针设备已离开用户代理边界时,mousemove
事件仍可能持续触发。
此事件在 DOM Level 2 Events 规范中曾被指定为不可取消,但后来因用户代理间的互操作性而更改为可取消。
3.4.5.9. mouseout
类型 | mouseout
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在指针设备离开某元素边界或元素不再位于主指针设备下方时分发此事件。此事件类型类似于 mouseleave
,但不同点在于它会冒泡,并且必须在指针设备从元素进入其后代元素边界时分发。
另请参阅 mouseover
事件类型。
3.4.5.10. mouseover
类型 | mouseover
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在指针设备进入某元素边界或元素移动到主指针设备下方时分发此事件。此事件类型类似于 mouseenter
,但不同点在于它会冒泡,且指针设备进入某元素边界时必须分发,即使该元素的祖先是同一事件目标,并且使用同一事件监听器实例。
另请参阅 mouseout
事件类型。
3.4.5.11. mouseup
类型 | mouseup
|
---|---|
接口 | MouseEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在指针设备按钮在某元素上释放时分发此事件。
在某些实现环境(如浏览器)中,即使指针设备已离开用户代理边界(如用户在按下鼠标按钮时开始拖动操作),也可以分发 mouseup
事件。
3.5. 滚轮事件
滚轮是一种可以在一个或多个空间维度上旋转的设备,可以与指针设备相关联。坐标系统取决于环境配置。
用户环境可能配置为将垂直滚动与y轴旋转相关联,水平滚动与x轴旋转相关联,缩放与z轴旋转相关联。
WheelEvent
对象的 deltaX、deltaY 和 deltaZ 属性表示沿各自轴的测量值,单位为像素、行或页。实际测量值是经过环境特定算法,将滚轮设备的实际旋转/移动转换为适当的值和单位后得到的。
用户环境设置可以自定义对滚轮设备实际旋转/移动的解释。例如,常见的有齿鼠标滚轮一次滚动可以产生162像素的测量(162只是示例值,实际值取决于用户代理的当前屏幕尺寸)。用户可以更改默认环境设置来加快鼠标滚轮速度,从而增加此数值。此外,部分鼠标滚轮软件支持加速(滚轮旋转越快,每次测量的 delta 越大),甚至支持亚像素旋转测量。因此,作者不能假定在一个用户代理中的某个旋转量会在所有用户代理中产生相同的delta值。
deltaX、deltaY 和 deltaZ 属性的符号(正或负)在多次分发 wheel
事件且实际滚轮设备旋转/移动方向一致时必须保持一致。如果用户代理将滚轮事件的默认行为设为滚动,则delta的符号应遵循右手坐标系:正的X、Y、Z轴分别指向文档的最右边、最下边和最远端(远离用户)。
各个用户代理(视环境和硬件配置而定)可能对同一物理滚轮操作有不同解释。例如,在触控板边缘从上到下进行一次垂直滑动可以被解释为向下滚动页面或向上平移页面(即分别导致正或负的 deltaY 值)。
用户代理在首次触发滚轮事件时,必须创建一次滚轮事件事务,以便在实现定义的时间范围内的所有后续滚轮事件都能定位到同一元素。滚轮事件事务是一系列与单个用户操作相关联的滚轮事件。该滚轮事件事务必须具有与首次滚轮事件发生时的最顶层事件目标相关联的事件目标。
在可滚动元素中定位的一系列滚轮事件可能是从子元素上方开始的,同一次用户操作的后续事件可能会发生在子元素上。
3.5.1. WheelEvent 接口
本规范中引入
WheelEvent
接口提供了与 wheel
事件相关的特定上下文信息。
要创建 WheelEvent
接口实例,请使用 WheelEvent
构造函数,并传递可选的 WheelEventInit
字典参数。
3.5.1.1. WheelEvent
[Exposed =Window ]interface :
WheelEvent MouseEvent {(
constructor DOMString ,
type optional WheelEventInit = {}); // DeltaModeCode
eventInitDict const unsigned long DOM_DELTA_PIXEL = 0x00;const unsigned long DOM_DELTA_LINE = 0x01;const unsigned long DOM_DELTA_PAGE = 0x02;readonly attribute double deltaX ;readonly attribute double deltaY ;readonly attribute double deltaZ ;readonly attribute unsigned long deltaMode ; };
DOM_DELTA_PIXEL
- delta 的单位必须为像素。这是大多数操作系统和实现配置下最常见的情况。
DOM_DELTA_LINE
- delta 的单位必须为文本行。许多表单控件采用此方式。
DOM_DELTA_PAGE
- delta 的单位必须为页面,可以定义为单个屏幕或标记的页面。
deltaX
, 类型为 double,只读-
在默认行为为滚动的用户代理中,值必须为事件未取消时沿x轴滚动的测量值(单位为像素、行或页)。否则,该值为实现特定的滚轮设备围绕x轴移动的测量值(单位为像素、行或页)。
此属性的未初始化值必须为
0.0
。 deltaY
, 类型为 double,只读-
在默认行为为滚动的用户代理中,值必须为事件未取消时沿y轴滚动的测量值(单位为像素、行或页)。否则,该值为实现特定的滚轮设备围绕y轴移动的测量值(单位为像素、行或页)。
此属性的未初始化值必须为
0.0
。 deltaZ
, 类型为 double,只读-
在默认行为为滚动的用户代理中,值必须为事件未取消时沿z轴滚动的测量值(单位为像素、行或页)。否则,该值为实现特定的滚轮设备围绕z轴移动的测量值(单位为像素、行或页)。
此属性的未初始化值必须为
0.0
。 deltaMode
, 类型为 unsigned long,只读-
deltaMode
属性包含 delta 值的单位指示。默认值为DOM_DELTA_PIXEL
(像素)。此属性必须设置为 DOM_DELTA 常量之一,用于指示 delta 值的单位。具体测量依赖于设备、操作系统和应用配置。
此属性的未初始化值必须为
0
。
3.5.1.2. WheelEventInit
dictionary :
WheelEventInit MouseEventInit {double deltaX = 0.0;double deltaY = 0.0;double deltaZ = 0.0;unsigned long deltaMode = 0; };
deltaX
, 类型为 double,默认值为0.0
- 参见
deltaZ
属性。 deltaY
, 类型为 double,默认值为0.0
- 参见
deltaZ
属性。 deltaZ
, 类型为 double,默认值为0.0
- 初始化
deltaZ
属性。此属性(以及deltaX
、deltaY
)的正值采用右手坐标系:X、Y、Z 轴分别指向文档最右、最下和最远(远离用户)。负值则为相反方向。 deltaMode
, 类型为 unsigned long,默认值为0
- 初始化
deltaMode
属性,枚举值为 0、1 或 2,分别表示滚动的像素量(DOM_DELTA_PIXEL
)、行数(DOM_DELTA_LINE
)或页数(DOM_DELTA_PAGE
),如果滚轮旋转会导致滚动。
3.5.2. 滚轮事件类型
3.5.2.1. wheel
类型 | wheel
|
---|---|
接口 | WheelEvent
|
同步 / 异步 | 异步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 视情况而定 |
可组合 | 是 |
默认行为 | 滚动(或缩放)文档 |
上下文 (可信事件) |
|
用户代理必须在鼠标滚轮围绕任一轴旋转,或等效输入设备(如鼠标球、某些平板或触控板等)模拟此操作时分发此事件。根据平台和输入设备,斜向滚轮delta可能以单个包含多个非零轴的 wheel
事件形式,或为每个非零轴分别分发多个 wheel
事件。
wheel
事件类型的典型默认行为是按指示的数量滚动(或在某些情况下缩放)文档。如果此事件被取消,实现不得滚动或缩放文档(或执行与此事件类型相关的其它实现特定默认行为)。
在某些用户代理或某些输入设备中,滚轮旋转速度会影响delta值,旋转速度越快,delta值越大。
3.5.2.2. 滚轮事件的可取消性
在滚轮事件上调用 preventDefault
可以阻止或中断滚动。为了获得最佳滚动性能,用户代理可能不会等待与滚动相关的每个滚轮事件都处理完毕再判断是否被取消。在这种情况下,用户代理应生成 cancelable
属性为
false
的 wheel
事件,表示无法使用 preventDefault
来阻止或中断滚动。否则
cancelable
将为 true
。
特别地,如果用户代理检测到没有非被动监听器,则只应生成不可取消的
wheel
事件。
3.6. 输入事件
输入事件是在 DOM 因用户操作(例如在可编辑区域键盘输入、删除或格式化文本等)直接更新或即将更新时发送的通知。
3.6.1. InputEvent 接口
3.6.1.1. InputEvent
在 DOM Level 3 中引入
[Exposed =Window ]interface :
InputEvent UIEvent {(
constructor DOMString ,
type optional InputEventInit = {});
eventInitDict readonly attribute USVString ?data ;readonly attribute boolean isComposing ;readonly attribute DOMString inputType ; };
data
, 类型为 USVString,只读,可为 null-
data
保存由输入法生成的字符值。它可以是一个 Unicode 字符或一个非空的 Unicode 字符序列 [Unicode]。字符应按照 Unicode 规范中的 NFC 归一化形式进行归一化,定义见 [UAX15]。 此属性可以包含空字符串。此属性的未初始化值必须为
null
。 isComposing
, 类型为 boolean,只读-
如果输入事件是在一个组合会话期间发生(即在
compositionstart
事件之后、对应的compositionend
事件之前),则为true
,否则为false
。此属性的未初始化值必须为
false
。 inputType
, 类型为 DOMString,只读-
inputType
包含一个字符串,用来标识与事件相关的输入类型。有效值列表参见 [Input-Events] 规范。
此属性的未初始化值必须为 空字符串
""
。
3.6.1.2. InputEventInit
dictionary :
InputEventInit UIEventInit {DOMString ?data =null ;boolean isComposing =false ;DOMString inputType = ""; };
data
, 类型为 DOMString,可为 null,默认值为null
- 初始化 InputEvent 对象的
data
属性。 isComposing
, 类型为 boolean,默认值为false
- 初始化 InputEvent 对象的
isComposing
属性。 inputType
, 类型为 DOMString,默认值为""
- 初始化 InputEvent 对象的
inputType
属性。
3.6.2. 输入事件顺序
本规范定义的输入事件必须按照特定顺序发生。
事件类型 | 备注 | |
---|---|---|
1 | beforeinput
| |
DOM 元素已更新 | ||
2 | input
|
3.6.3. 输入事件类型
3.6.3.1. beforeinput
类型 | beforeinput
|
---|---|
接口 | InputEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element (具体如 HTMLInputElement 控件类型等)或启用
contenteditable 属性的任意 Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 更新 DOM 元素 |
上下文 (可信事件) |
|
用户代理必须在 DOM 即将更新时分发此事件。
3.6.3.2. input
类型 | input
|
---|---|
接口 | InputEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element (具体如 HTMLInputElement 控件类型等)或启用
contenteditable 属性的任意 Element
|
可取消 | 否 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在 DOM 更新后立即分发此事件。
3.7. 键盘事件
键盘事件是依赖于设备的,即它们依赖于输入设备的能力以及在操作系统中的映射方式。详情请参阅键盘事件和按键值,其中包括键盘事件与组合事件结合使用的示例。根据字符生成设备,可能不会生成键盘事件。
键盘事件只是提供文本输入的一种方式。在编辑场景下,也可以考虑使用 InputEvent
作为键盘事件的替代或补充。
3.7.1. KeyboardEvent 接口
本规范中引入
KeyboardEvent
接口提供与键盘设备相关的特定上下文信息。每个键盘事件都通过一个值引用一个按键。键盘事件通常会发送到拥有焦点的元素。
KeyboardEvent
接口为一些常用修饰键提供了便捷属性:ctrlKey
、
shiftKey
、
altKey
、
metaKey
。
这些属性等同于使用 getModifierState()
方法,并分别传入 Control
、Shift
、Alt
或 Meta
。
要创建 KeyboardEvent
接口实例,请使用 KeyboardEvent
构造函数,并传递可选的 KeyboardEventInit
字典参数。
3.7.1.1. KeyboardEvent
[Exposed =Window ]interface :
KeyboardEvent UIEvent {(
constructor DOMString ,
type optional KeyboardEventInit = {}); // KeyLocationCode
eventInitDict 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
修饰键激活,则为true
。此属性的未初始化值必须为
false
。 altKey
, 类型为 boolean,只读-
如果
Alt
(替代/Option)修饰键激活,则为true
。此属性的未初始化值必须为
false
。 metaKey
, 类型为 boolean,只读-
如果
Meta
修饰键激活,则为true
。在 Mac 系统上,
"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.7.1.2. KeyboardEventInit
dictionary :
KeyboardEventInit EventModifierInit {DOMString key = "";DOMString code = "";unsigned long location = 0;boolean repeat =false ;boolean isComposing =false ; };
key
, 类型为 DOMString,默认值为""
- 初始化 KeyboardEvent 对象的
key
属性为表示按键含义的 Unicode 字符串(考虑所有键盘修饰键,如 shift 状态)。该值为最终有效值。如果按键不是可打印字符,则应为 [UIEvents-Key] 中定义的按键值之一。 code
, 类型为 DOMString,默认值为""
- 初始化 KeyboardEvent 对象的
code
属性为表示按下按键的 Unicode 字符串,忽略键盘布局等修饰。该值应为 [UIEvents-Code] 中定义的代码值之一。 location
, 类型为 unsigned long,默认值为0
-
初始化 KeyboardEvent 对象的
location
属性为如下位置数值常量之一:-
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
的取值或行为。符合规范的 UI Events 实现中,内容作者应使用 key
和 code
。
更多信息参见关于传统按键属性的附录。
为兼容现有内容,虚拟键盘(如屏幕输入设备上的软件键盘)应生成正常范围的键盘事件,即使它们没有物理按键。
在某些实现或系统配置下,部分按键事件或其值可能会被正在使用的输入法抑制。
3.7.2. 键盘事件按键位置
location
属性可用于区分由键盘上不同物理按键生成的 key
值,例如左右 Shift
键或物理方向键与数字键盘方向键(NumLock
关闭时)。
下表定义了键盘上具有多个位置的特殊按键的有效 location
取值:
KeyboardEvent
. key
| 有效 location
取值
|
---|---|
"Shift" ,
"Control" ,
"Alt" ,
"Meta"
| DOM_KEY_LOCATION_LEFT ,
DOM_KEY_LOCATION_RIGHT
|
"ArrowDown" ,
"ArrowLeft" ,
"ArrowRight" ,
"ArrowUp"
| DOM_KEY_LOCATION_STANDARD ,
DOM_KEY_LOCATION_NUMPAD
|
"End" ,
"Home" ,
"PageDown" ,
"PageUp"
| DOM_KEY_LOCATION_STANDARD ,
DOM_KEY_LOCATION_NUMPAD
|
"0" , "1" , "2" ,
"2" , "4" , "5" ,
"6" , "7" , "8" ,
"9" , "." , "Enter" ,
"+" , "-" , "*" ,
"/"
| DOM_KEY_LOCATION_STANDARD ,
DOM_KEY_LOCATION_NUMPAD
|
对于未在表中列出的所有其它按键,location
属性必须始终设置为 DOM_KEY_LOCATION_STANDARD
。
3.7.3. KeyboardEvent 算法
3.7.3.1. KeyboardEvent 的全局状态
3.7.3.1.1. 用户代理级状态
UA 必须维护以下用于整个用户代理的共享值。
一个 按键修饰状态 (初始为空),用于记录系统上每个修饰键的当前状态。
3.7.4. 键盘事件顺序
本规范定义的键盘事件针对任意按键按如下固定顺序发生:
事件类型 | 备注 | |
---|---|---|
1 | keydown
| |
2 | beforeinput
| (仅限会产生字符值的按键) |
与此按键相关的任何默认行为,如向 DOM 插入字符。 | ||
3 | input
| (仅限已更新 DOM 的按键) |
作为持续按住按键的结果产生的任何事件(见下文)。 | ||
4 | keyup
|
如果按键被持续按下,则以下事件可能会以依赖环境的速率重复:
事件类型 | 备注 | |
---|---|---|
1 | keydown
| (repeat
属性为 true )
|
2 | beforeinput
| (仅限会产生字符值的按键) |
与此按键相关的任何默认行为,如向 DOM 插入字符。 | ||
3 | input
| (仅限已更新 DOM 的按键) |
通常,与某个按键关联的默认行为会在 keyup
事件分发前完成。这可能会使 keyup
事件略有延迟(但一般不可察觉)。
按键事件的事件目标为当前聚焦并处理键盘操作的元素。通常为
HTML input
元素或可编辑文本元素,但也可以是宿主语言定义用于接受键盘输入(如激活快捷键或触发其他行为)的元素。如果没有合适的元素获得焦点,事件目标将为 HTML body 元素(如可用),否则为根元素。
事件目标在不同键盘事件间可能发生变化。例如,keydown
事件针对 Tab
键时,事件目标可能与同一次击键的
keyup
事件不同。
3.7.5. 键盘事件类型
3.7.5.1. keydown
类型 | keydown
|
---|---|
接口 | KeyboardEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 视情况而定:beforeinput 和 input 事件;启动文本输入法系统;blur 和 focus 事件;keypress
事件(如支持);激活行为;其他事件
|
上下文 (可信事件) |
|
用户代理必须在按下按键时分发此事件。keydown
事件类型依赖设备,取决于输入设备的能力及其在操作系统中的映射。该事件类型必须在按键映射之后生成,并且必须在与同一按键相关的 beforeinput
、input
和 keyup
事件之前分发。
keydown
事件的默认行为取决于按键:
-
如果按键与字符关联,默认行为必须是分发一个
beforeinput
事件,紧接着一个input
事件。如果按键与多个字符关联(如宏或某些死键序列),默认行为必须为每个字符分发一组beforeinput
/input
事件 -
如果按键与文本输入法系统相关联,则默认行为必须是启动该系统
-
如果按键是
Tab
键,默认行为必须是将文档焦点从当前焦点元素(如有)转移到新焦点元素,详见焦点事件类型 -
如果按键是
Enter
或click
事件,以及一个DOMActivate
事件(如用户代理支持该事件类型)。
如果该事件被取消,则相关事件类型不得分发,相关操作也不得执行。
keydown
和 keyup
事件传统上用于检测任意按键,而不仅是那些能产生字符值的按键。
3.7.5.2. keyup
类型 | keyup
|
---|---|
接口 | KeyboardEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
用户代理必须在按键释放时分发此事件。keyup
事件类型依赖设备,取决于输入设备的能力及其在操作系统中的映射。该事件类型必须在按键映射之后生成,并且必须在与同一按键相关的 keydown
、beforeinput
和
input
事件之后分发。
3.8. 组合事件
组合事件提供了除键盘事件之外的补充或替代文本输入方式,以支持输入键盘上不常见的字符。例如,组合事件可以用于在标准美式键盘上为字符添加重音符号,构建亚洲多字母语言的字形(通过基础部件或类别),在移动设备键盘上通过组合按键选择词语,或通过语音识别处理器将语音命令转换为文本。有关组合事件与键盘事件结合使用的示例,请参阅 § 4 键盘事件和按键值。
从概念上讲,一个组合会话包括一个 compositionstart
事件、一个或多个 compositionupdate
事件,以及一个
compositionend
事件,在每次会话的每个“阶段”之间,data
属性的值会持续存在。
注意: 当组合会话处于活动状态时,如果输入设备为键盘,则仍会向 DOM 派发键盘事件。详细顺序见 compositionstart
事件说明及 IME
部分。
并非所有 输入法 (IME) 系统或设备都会向 DOM 提供所需数据,因此活动的组合字符串(“候选窗口”或“候选菜单选项”)可能无法通过此接口获得,在这种情况下,选择内容可以用空字符串表示。
3.8.1. CompositionEvent 接口
本规范中引入
CompositionEvent
接口提供了与组合事件相关的具体上下文信息。
要创建 CompositionEvent
接口实例,请使用 CompositionEvent
构造函数,并传递可选的 CompositionEventInit
字典参数。
3.8.1.1. CompositionEvent
[Exposed =Window ]interface :
CompositionEvent UIEvent {(
constructor DOMString ,
type optional CompositionEventInit = {});
eventInitDict readonly attribute USVString data ; };
data
, 类型为 USVString,只读-
data
保存由输入法生成的字符值。它可以是一个 Unicode 字符,也可以是一个非空的 Unicode 字符序列 [Unicode]。字符应按照 Unicode 规范中的 NFC 归一化形式进行归一化,定义见 [UAX15]。此属性可以为空字符串。此属性的未初始化值必须为
""
(空字符串)。
3.8.1.2. CompositionEventInit
dictionary :
CompositionEventInit UIEventInit {DOMString data = ""; };
data
, 类型为 DOMString,默认值为""
- 初始化 CompositionEvent 对象的
data
属性为 IME 组合生成的字符。
3.8.2. 组合事件顺序
本规范定义的组合事件必须按以下固定顺序发生:
事件类型 | 备注 | |
---|---|---|
1 | compositionstart
| |
2 | compositionupdate
| 多次事件 |
3 | compositionend
|
3.8.3. 手写识别系统
以下示例描述了使用手写识别系统(如在笔平板上)组合文本片段“text”时的可能事件顺序,采用组合事件进行建模:
事件类型 | CompositionEvent data
| 备注 | |
---|---|---|---|
1 | compositionstart
| ""
| |
用户在平板表面书写单词 | |||
2 | compositionupdate
| "test"
| |
用户拒绝第一个单词建议,选择不同的匹配词 | |||
3 | compositionupdate
| "text"
| |
4 | compositionend
| "text"
|
3.8.4. 取消组合事件
如果 keydown
事件被取消,则因该 keydown
事件而产生的任何组合事件不应被分发:
事件类型 | 备注 | |
---|---|---|
1 | keydown
| 已阻止默认行为,如调用
preventDefault() 。
|
不会分发组合事件 | ||
2 | keyup
|
如果初始 compositionstart
事件被取消,则文本组合会话应被终止。无论组合会话是否终止,compositionend
事件都必须发送。
事件类型 | 备注 | |
---|---|---|
1 | keydown
| |
2 | compositionstart
| 已阻止默认行为,如调用
preventDefault() 。
|
不会分发组合事件 | ||
3 | compositionend
| |
4 | keyup
|
3.8.5. 组合期间的按键事件
在组合会话期间,keydown
和 keyup
事件仍必须被发送,并且这些事件的
isComposing
属性必须为 true
。
事件类型 | KeyboardEvent isComposing
| 备注 | |
---|---|---|---|
1 | keydown
| false | 这是启动组合的按键事件。 |
2 | compositionstart
| ||
3 | compositionupdate
| ||
4 | keyup
| true | |
... | 组合会话期间发送的所有按键事件必须将 isComposing 设为 true 。
| ||
5 | keydown
| true | 这是退出组合的按键事件。 |
6 | compositionend
| ||
7 | keyup
| false |
3.8.6. 组合期间的输入事件
在组合会话期间,compositionupdate
必须在 beforeinput
发送之后,但在 input
事件发送之前分发。
事件类型 | 备注 | |
---|---|---|
1 | beforeinput
| |
2 | compositionupdate
| |
此时会进行任何 DOM 更新。 | ||
3 | input
|
大多数输入法不支持在组合会话期间取消更新。
beforeinput
和 input
事件会与
compositionupdate
事件一同发送,只要组合相关 DOM 被更新。由于 compositionend
事件不会导致 DOM 更新,因此此时不应发送 beforeinput
和
input
事件。
事件类型 | 备注 | |
---|---|---|
1 | beforeinput
| 取消此事件将阻止 DOM 更新和 input 事件。
|
2 | compositionupdate
| |
此时会进行任何 DOM 更新。 | ||
3 | input
| 仅当 DOM 被更新时发送。 |
4 | compositionend
|
3.8.7. 组合事件类型
3.8.7.1. compositionstart
类型 | compositionstart
|
---|---|
接口 | CompositionEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 是 |
可组合 | 是 |
默认行为 | 启用文本输入法系统时,开始新组合会话 |
上下文 (可信事件) |
用户代理必须在启用文本输入法系统并准备开始(或已经开始,取决于文本输入法系统)新组合会话时分发此事件。该事件类型依赖设备,可能依赖文本转换系统的能力及其在操作系统中的映射。当键盘用于输入法编辑器时,此事件类型在
keydown
事件后生成,但语音或手写识别系统可以在没有键盘事件的情况下发送该事件类型。部分实现可能会用文档当前选中的文本填充 data
属性(用于编辑和替换),否则 data
属性值必须为空字符串。
该事件必须在文本输入法系统开始新组合会话,并且在因组合过程修改 DOM 之前立即分发。该事件的默认行为是文本输入法系统开始新组合会话。如果该事件被取消,文本输入法系统应丢弃当前组合会话。
取消 compositionstart
事件类型不同于取消文本输入法系统本身(如点击取消按钮或关闭输入法窗口)。
部分输入法不支持取消正在进行的组合会话(如 GTK 目前没有此类 API)。在这些情况下,调用 preventDefault()
不会阻止该事件的默认行为。
3.8.7.2. compositionupdate
类型 | compositionupdate
|
---|---|
接口 | CompositionEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 否 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
用户代理应在组合会话期间,当文本输入法系统用新字符更新活动文本片段(即 data
字符串发生变化)时分发此事件。
在需要将组合过程与输入控件保持同步的文本输入法系统中,compositionupdate
事件必须在控件更新之前分发。
部分文本输入法系统可能不会向 DOM 公开此信息,组合过程中不会触发该事件。
如果组合会话被取消,则该事件会在 compositionend
事件之前立即触发,并且 data
属性值将为空字符串。
3.8.7.3. compositionend
类型 | compositionend
|
---|---|
接口 | CompositionEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Element
|
可取消 | 否 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
用户代理必须在文本输入法系统完成或取消当前组合会话时分发此事件,并且 compositionend
事件必须在控件更新后分发。
4. 键盘事件与按键值
本章节包含有关键盘事件的必要信息:
-
键盘布局、映射和按键值的说明。
-
按键之间的关系,如 死键 或修饰键。
-
键盘事件与其默认行为之间的关系。
-
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
的关系
key
key
属性适用于关注按键实际意义(考虑当前键盘布局和输入法,死键有独特key
值)的人群。典型用例:检测修饰键或裸修饰键(如响应快捷键)。code
code
属性适用于关注用户实际按下哪个物理按键的人群,不受布局影响。典型用例:检测 WASD 键(如游戏的移动控制)或拦截所有按键(如远程桌面客户端将所有按键发送到远程主机)。
4.2.3. code
示例
键盘布局 | KeyboardEvent key
| KeyboardEvent code
| 备注 |
---|---|---|---|
美式 | "Alt"
| "AltLeft"
| DOM_KEY_LOCATION_LEFT
|
法式 | "Alt"
| "AltLeft"
| DOM_KEY_LOCATION_LEFT
|
美式 | "Alt"
| "AltRight"
| DOM_KEY_LOCATION_RIGHT
|
法式 | "AltGraph"
| "AltRight"
| DOM_KEY_LOCATION_RIGHT
|
在此示例中,检查 key
属性可以匹配 Alt
,无需关心按下的是左 Alt 还是右 Alt 键。检查 code
属性可以匹配右 Alt 键("AltRight"
),无需关心当前布局。
注意,在法式键盘示例中,Alt
和 AltGraph
键仍然保留左/右位置,即使每种只各有一个键。
键盘布局 | KeyboardEvent key
| KeyboardEvent code
| 备注 |
---|---|---|---|
美式 | "'"
| "Quote"
| |
日文 | ":"
| "Quote"
| |
美式国际 | "Dead"
| "Quote"
|
"2"
键(按下和未按下
Shift)在不同键盘布局上的情况。
键盘布局 | KeyboardEvent key
| KeyboardEvent code
| 备注 |
---|---|---|---|
美式 | "2"
| "Digit2"
| |
美式 | "@"
| "Digit2"
| shiftKey
|
英式 | "2"
| "Digit2"
| |
英式 | """
| "Digit2"
| shiftKey
|
法式 | "é"
| "Digit2"
| |
法式 | "2"
| "Digit2"
| shiftKey
|
Shift
和 2
对比下述两个按键事件序列的属性值。它们在美式键盘上都能输入 "@"
字符,但释放按键的顺序不同。第一个序列为:Shift
(按下)、2
(按下)、2
(释放)、Shift
(释放)。
事件类型 | KeyboardEvent key
| KeyboardEvent code
| 备注 | |
---|---|---|---|---|
1 | keydown
| "Shift"
| "ShiftLeft"
| DOM_KEY_LOCATION_LEFT
|
2 | keydown
| "@"
| "Digit2"
| shiftKey
|
3 | keypress
| "@"
| "Digit2"
| (如支持) |
4 | keyup
| "@"
| "Digit2"
| shiftKey
|
5 | keyup
| "Shift"
| "ShiftLeft"
| DOM_KEY_LOCATION_LEFT
|
第二个序列中,Shift 在 2 之前释放,事件顺序为:Shift
(按下)、2
(按下)、Shift
(释放)、2
(释放)。
事件类型 | KeyboardEvent key
| KeyboardEvent code
| 备注 | |
---|---|---|---|---|
1 | keydown
| "Shift"
| "ShiftLeft"
| DOM_KEY_LOCATION_LEFT
|
2 | keydown
| "@"
| "Digit2"
| shiftKey
|
3 | keypress
| "@"
| "Digit2"
| (如支持) |
4 | keyup
| "Shift"
| "ShiftLeft"
| DOM_KEY_LOCATION_LEFT
|
5 | keyup
| "2"
| "Digit2"
|
请注意,key
属性在 "2"
键的 keydown 和 keyup 事件之间值不同。而 code
属性则始终提供一个不受当前修饰键状态影响的稳定值。
4.2.4.
code
与虚拟键盘
code
属性对于虚拟键盘(以及遥控器和和弦键盘)的用处并不明显。通常,如果虚拟(或遥控)键盘模仿标准键盘的布局和功能,则也必须适当设置 code
属性。对于不模仿标准键盘布局的键盘,code
属性可以设置为标准键盘上最接近的键,也可以不设置(留空)。
对于虚拟键盘中根据修饰键状态产生不同值的按键,code
值应为设备处于出厂重置状态时按下该按钮时生成的 key
值。
4.3. 键盘事件 key
值
按键值是一个
DOMString
,用于表示键盘上的任意按键(无论位置或状态),以其所产生的值区分。这些按键值可以作为实现生成的键盘事件的返回值,也可以由内容作者用作输入(如用于键盘快捷键)。
合法的 key
值列表定义在 [UIEvents-Key] 中。
内容作者可以通过 key
属性检测按键被按下时的值,可以获得大写或小写字母、数字、符号或其他能产生字符的按键的字符值,也可以获得控制键、修饰键、功能键或其他不产生字符的按键的按键值。这些值可用于监控特定输入字符串、检测并响应修饰键与其他输入(如鼠标)组合、创建虚拟键盘或其他用途。
按键值也可以用于字符串比较、作为标签属性值(如 HTML accesskey
),或其它相关用途。符合规范的宿主语言应允许内容作者使用按键值的两个等价字符串之一:字符值或按键值。
虽然实现会根据平台或键盘布局独立使用最相关的按键值,但内容作者不能假设键盘设备都能生成这些值。在用作快捷键组合时,可以考虑使用数字和功能键(
([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
)时可能的事件序列:
事件类型 | KeyboardEvent key
| 修饰键 | 备注 | |
---|---|---|---|---|
1 | keydown
| "Shift"
| shiftKey
| |
2 | keydown
| "Q"
| shiftKey
| 拉丁大写字母 Q |
3 | beforeinput
| |||
4 | input
| |||
5 | keyup
| "Q"
| shiftKey
| |
6 | keyup
| "Shift"
|
Shift
键,再释放 Q
键。此时 Q
键在 keyup
事件中的值会变为未修饰状态:
事件类型 | KeyboardEvent key
| 修饰键 | 备注 | |
---|---|---|---|---|
1 | keydown
| "Shift"
| shiftKey
| |
2 | keydown
| "Q"
| shiftKey
| 拉丁大写字母 Q |
3 | beforeinput
| |||
4 | input
| |||
5 | keyup
| "Shift"
| ||
6 | keyup
| "q"
| 拉丁小写字母 Q |
事件类型 | KeyboardEvent key
| 修饰键 | 备注 | |
---|---|---|---|---|
1 | keydown
| "Control"
| ctrlKey
| |
2 | keydown
| "v"
| ctrlKey
| 拉丁小写字母 V |
不生成 beforeinput 或 input
事件。
| ||||
3 | keyup
| "v"
| ctrlKey
| 拉丁小写字母 V |
4 | keyup
| "Control"
|
Shift
和 Control
时的事件序列:
事件类型 | KeyboardEvent key
| 修饰键 | 备注 | |
---|---|---|---|---|
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"
|
事件类型 | KeyboardEvent key
| 修饰键 | 备注 | |
---|---|---|---|---|
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 的首选。
事件类型 | KeyboardEvent key
| KeyboardEvent isComposing
| CompositionEvent data
| 备注 | |
---|---|---|---|---|---|
1 | keydown
| "Dead"
| false
| 组合抑扬符(死键) | |
2 | compositionstart
| ""
| |||
3 | compositionupdate
| U+0302
| |||
4 | keyup
| "Dead"
| true
| ||
5 | keydown
| "ê"
| true
| ||
6 | compositionupdate
| "ê"
| |||
7 | compositionend
| "ê"
| |||
8 | keyup
| "e"
| false
| 拉丁小写字母 e |
在第二个 keydown
事件(第5步),按键值(假定事件未被屏蔽)不会是 "e"
(拉丁小写字母 e),因为用户代理接收到的值已被死键操作修改。
当用户在按下死键后输入了不支持的基础字符(即该基础字符没有激活的变音符可用),该过程可能会被中断:
事件类型 | KeyboardEvent key
| KeyboardEvent isComposing
| CompositionEvent data
| 备注 | |
---|---|---|---|---|---|
1 | keydown
| "Dead"
| false
| 组合抑扬符(死键) | |
2 | compositionstart
| ""
| |||
3 | compositionupdate
| U+0302
| |||
4 | keyup
| "Dead"
| true
| ||
5 | keydown
| "q"
| true
| 拉丁小写字母 q | |
6 | compositionupdate
| ""
| |||
7 | compositionend
| ""
| |||
8 | keyup
| "q"
| false
|
4.3.3. 输入法编辑器
本规范通过 CompositionEvent
接口和相应事件,包含了输入法编辑器(IME)的模型。
然而,组合事件与键盘事件并不总是存在一一对应关系。例如,收到 keydown
事件且按键值为 Accept
时,并不一定意味着当前在输入法中选中的文本被“接受”,只表示有一次按键发生,与 输入法的“接受”功能无关(通常在多数输入法系统中会触发 compositionend
事件)。键盘事件无法用于判断输入法编辑器的当前状态,应通过 data
属性在 CompositionEvent
接口获取。此外,不同的输入法系统和设备功能不同,激活这些功能的按键也不同,Convert
和 Accept
键也可能由其他可用按键表示。键盘事件对应于键盘布局映射之后由输入设备生成的事件。
在部分实现或系统配置下,部分按键事件及其值可能会被正在使用的输入法抑制。
下例展示了通过日语输入法生成 Unicode 字符 "市"
(汉字,CJK统一表意文字之一)的一组可能按键序列。假定输入法已激活并处于日文罗马字输入模式。Convert
和 Accept
键可能被其他按键替换,具体取决于输入设备和输入法配置,例如分别可以是 U+0020
(空格键)和 Enter
。
"詩"
(诗)和 "市"
(市)为同音字,都读作
し(shi/si),用户需用 Convert
键选择正确选项。
事件类型 | KeyboardEvent key
| KeyboardEvent isComposing
| CompositionEvent data
| 备注 | |
---|---|---|---|---|---|
1 | keydown
| "s"
| false
| 拉丁小写字母 S | |
2 | compositionstart
| ""
| |||
3 | beforeinput
| ||||
4 | compositionupdate
| "s"
| |||
DOM 已更新 | |||||
5 | input
| ||||
6 | keyup
| "s"
| true
| ||
7 | keydown
| "i"
| true
| 拉丁小写字母 I | |
8 | beforeinput
| ||||
9 | compositionupdate
| "し"
| shi | ||
DOM 已更新 | |||||
10 | input
| ||||
11 | keyup
| "i"
| true
| ||
12 | keydown
| "Convert"
| true
| 转换 | |
13 | beforeinput
| ||||
14 | compositionupdate
| "詩"
| "诗" | ||
DOM 已更新 | |||||
15 | input
| ||||
16 | keyup
| "Convert"
| true
| ||
17 | keydown
| "Convert"
| true
| 转换 | |
18 | beforeinput
| ||||
19 | compositionupdate
| "市"
| "市" | ||
DOM 已更新 | |||||
20 | input
| ||||
21 | keyup
| "Convert"
| true
| ||
22 | keydown
| "Accept"
| true
| 接受 | |
23 | compositionend
| "市"
| |||
24 | keyup
| "Accept"
| false
|
IME 组合也可以被取消,条件与上述示例相同。Cancel
键也可能由其他按键替换,具体取决于输入设备和输入法配置,例如可以是 U+001B
(Esc键)。
事件类型 | KeyboardEvent key
| KeyboardEvent isComposing
| CompositionEvent data
| 备注 | |
---|---|---|---|---|---|
1 | keydown
| "s"
| false
| 拉丁小写字母 S | |
2 | compositionstart
| ""
| |||
3 | compositionupdate
| "s"
| |||
4 | keyup
| "s"
| true
| ||
5 | keydown
| "i"
| true
| 拉丁小写字母 I | |
6 | compositionupdate
| "し"
| shi | ||
7 | keyup
| "i"
| true
| ||
8 | keydown
| "Convert"
| true
| 转换 | |
9 | compositionupdate
| "詩"
| "诗" | ||
10 | keyup
| "Convert"
| true
| ||
11 | keydown
| "Convert"
| true
| 转换 | |
12 | compositionupdate
| "市"
| "市" | ||
13 | keyup
| "Convert"
| true
| ||
14 | keydown
| "Cancel"
| true
| 取消 | |
15 | compositionupdate
| ""
| |||
16 | compositionend
| ""
| |||
17 | keyup
| "Cancel"
| false
|
部分输入法编辑器(如 MacOS 操作系统上的输入法)可能会在取消组合前将组合数据属性设为空字符串。
4.3.3.1. 输入法编辑器模式按键
某些设备上的部分按键用于激活输入法编辑器功能,或用于更改活动输入法编辑器的模式。不同设备或语言模式可以自定义这些按键。本规范定义了如下用于该目的的按键:"Alphanumeric"
、
"CodeInput"
、
"FinalMode"
、
"HangulMode"
、
"HanjaMode"
、
"Hiragana"
、
"JunjaMode"
、
"KanaMode"
、
"KanjiMode"
、
"Katakana"
和
"Romaji"
。当按下这些按键之一且当前没有输入法激活时,预期会以该按键指示的模式激活相应输入法(如可用)。如果按键按下时已有输入法激活,则当前输入法可能切换到指定模式,也可能启动不同的输入法,或者该按键可能被忽略,具体取决于设备和应用。
本规范还定义了其它专门用于输入法编辑器的按键:"Accept"
、"AllCandidates"
、
"Cancel"
、"Convert"
、"Compose"
、"Zenkaku"
(全角)、"Hankaku"
(半角)、"NextCandidate"
、
"NonConvert"
,
以及 "PreviousCandidate"
。这些按键的具体功能未在本规范定义——详情参见其它输入法相关资源。
具有输入法编辑器功能的按键不仅限于此用途,也可以有其他设备或实现特定的用途。
4.3.4. 默认行为与可取消的键盘事件
取消默认行为的keydown
事件不会影响其对应的keyup
事件,但必须阻止对应的beforeinput
和input
(如果支持还包括keypress
)事件的生成。下例展示美式键盘(US mapping)输入 Unicode 字符 Q(拉丁大写字母
Q)时的按键序列:
事件类型 | KeyboardEvent key
| InputEvent data
| 修饰键 | 备注 | |
---|---|---|---|---|---|
1 | keydown
| "Shift"
| shiftKey
| ||
2 | keydown
| "Q"
| shiftKey
| 已阻止默认行为,如调用 preventDefault() 。
| |
不会生成 beforeinput 或 input
(或 keypress ,如支持)事件
| |||||
3 | keyup
| "Q"
| shiftKey
| ||
4 | keyup
| "Shift"
|
如果按键为修饰键,则按键操作必须仍然影响修饰键状态。下例展示美式键盘输入 Unicode 字符 Q(拉丁大写字母 Q)时可能的按键序列:
事件类型 | KeyboardEvent key
| InputEvent data
| 修饰键 | 备注 | |
---|---|---|---|---|---|
1 | keydown
| "Shift"
| shiftKey
| 已阻止默认行为,如调用 preventDefault() 。
| |
2 | keydown
| "Q"
| shiftKey
| ||
3 | beforeinput
| "Q"
| |||
4 | input
| ||||
5 | keyup
| "Q"
| shiftKey
| ||
6 | keyup
| "Shift"
|
如果按键属于一组多个按键序列(无论是死键还是输入法编辑器序列),只有在keydown
事件上取消了默认行为,该按键才能被忽略(不计入序列)。在keyup
事件上取消死键不会影响beforeinput
或input
事件。下例在法语键盘(French mapping)未激活修饰键时,使用死键 "Dead"
(U+0302
组合抑扬符死键)和 "e"
(U+0065
,拉丁小写字母 e 键):
事件类型 | KeyboardEvent key
| InputEvent data
| 备注 | |
---|---|---|---|---|
1 | keydown
| "Dead"
| 已阻止默认行为,如调用 preventDefault() 。
| |
2 | keyup
| "Dead"
| ||
3 | keydown
| "e"
| ||
4 | beforeinput
| "e"
| ||
5 | input
| |||
6 | keyup
| "e"
|
5. 外部算法
本节包含本规范所需,但更应由其他规范托管的算法。
本节旨在作为这些定义的临时归属地,最终应将其迁移到更合适的规范中,届时可删除本节。
5.1. 核心 DOM 算法
下述算法应迁移到其他地方……
5.1.1. 命中测试
- 输入
-
pos,相对于视口的 x,y 坐标
- 输出
-
pos 位置最前面的 DOM 元素
为适配 inert 或 disabled 元素,应调用 elementsFromPoint 并排除无效元素
-
返回 [CSSOM-View] 的 elementFromPoint,参数为 pos
5.1.2. 计算 DOM 路径
- 输入
-
element,起始元素
- 输出
-
给定元素的祖先元素列表
-
令 path = 一个包含 element 的列表
该定义需完善如何将祖先添加到 path。
-
返回 path
5.2. PointerLock 算法
下述算法应迁移到 [PointerLock] 规范。
5.2.1. PointerLock 全局状态
5.2.1.1. 窗口级状态
UA 必须维护如下窗口级共享值。
一个 last mouse move 值(初始为未定义),记录最近一次 mousemove 事件的位置。
5.2.2. 初始化 MouseEvent 的 PointerLock 属性
- 输入
-
event,一个
MouseEvent
- 输出
-
无
5.2.3. 设置 mousemove 的 PointerLock 属性
- 输入
-
event,一个
MouseEvent
- 输出
-
无
-
如果 event.
type
不是 "mousemove",则退出 -
如果 last mouse move 未定义,则
-
否则,
-
设置 event.
movementX
= event.screenX
- last mouse move 的 x 坐标 -
设置 event.
movementY
= event.screenX
- last mouse move 的 y 坐标
-
-
设置 last mouse move = ( event.
screenX
, event.screenY
)
5.3. PointerEvent 算法
下述算法应迁移到 [PointerEvents3] 规范。
5.3.1. 初始化 PointerEvent
- 输入
-
event,要初始化的
PointerEvent
eventType,包含事件类型的 DOMString
eventTarget,事件的
EventTarget
- 输出
-
无
-
用 event、eventType 和 eventTarget 初始化 MouseEvent
TODO - 初始化 pointerevent 属性
5.3.2. 创建 PointerEvent
- 输入
-
eventType,包含事件类型的 DOMString
eventTarget,事件的
EventTarget
- 输出
-
无
-
令 event = 创建新事件,类型为
PointerEvent
-
用 event、eventType 和 eventTarget 初始化 PointerEvent
-
返回 event
5.3.3. 由 MouseEvent 创建 PointerEvent
- 输入
-
eventType,包含事件类型的 DOMString
mouseevent,对应的
MouseEvent
- 输出
-
无
-
令 event = 创建新事件,类型为
PointerEvent
-
令 target = mouseevent.
target
-
用 event、eventType 和 target 初始化 PointerEvent
-
将 MouseEvent 属性从 mouseevent 复制到 event
-
返回 event
5.3.4. 可能发送 pointerout 事件
- 输入
-
mouseout,对应的 mouseout
MouseEvent
- 输出
-
无
-
令 pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent
-
设置 pointerevent 属性
TODO
-
令 target = mouseout.
target
-
派发 pointerout 到 target
5.3.5. 可能发送 pointerleave 事件
- 输入
-
mouseout,对应的 mouseout
MouseEvent
- 输出
-
无
-
令 pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent
-
设置 pointerevent 属性
TODO
-
令 target = mouseout.
target
-
派发 pointerout 到 target
5.3.6. 可能发送 pointerover 事件
- 输入
-
mouseout,对应的 mouseout
MouseEvent
- 输出
-
无
-
令 pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent
-
设置 pointerevent 属性
TODO
-
令 target = mouseout.
target
-
派发 pointerout 到 target
5.3.7. 可能发送 pointerenter 事件
- 输入
-
mouseout,对应的 mouseout
MouseEvent
- 输出
-
无
-
令 pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent
-
设置 pointerevent 属性
TODO
-
令 target = mouseout.
target
-
派发 pointerout 到 target
5.3.8. 可能发送 pointermove 事件
- 输入
-
mouseout,对应的 mouseout
MouseEvent
- 输出
-
无
这个方法可以同时发送 pointermove 和 pointerrawupdate 吗?还是需要两个方法?
如何合理定义 pointermove 事件的合并行为?
-
令 pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent
-
设置 pointerevent 属性
TODO
-
令 target = mouseout.
target
-
派发 pointerout 到 target
5.3.9. 可能发送 pointerdown 事件
- 输入
-
mouseout,对应的 mouseout
MouseEvent
- 输出
-
无
与 mousedown 事件不同,当多个按钮被同时按下时,pointerdown 事件不会嵌套。 传递 MouseEvent 以便字段可以复制到 PointerEvent 中。
-
令 pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent
-
设置 pointerevent 属性
TODO
-
令 target = mouseout.
target
-
派发 pointerout 到 target
5.3.10. 可能发送 pointerup 事件
- 输入
-
mouseout,对应的 mouseout
MouseEvent
- 输出
-
无
与 mouseup 事件不同,当多个按钮被同时按下时,pointerup 事件不会嵌套。 传递 MouseEvent 以便字段可以复制到 PointerEvent 中。
-
令 pointerout = 用 "pointerout" 和 mouseout 由 MouseEvent 创建 PointerEvent
-
设置 pointerevent 属性
TODO
-
令 target = mouseout.
target
-
派发 pointerout 到 target
6. 遗留事件初始化器
本节为规范性内容。 下列特性已废弃,仅应由用户代理实现,以兼容旧版软件。
本规范早期版本在接口上包含初始化方法(如 initMouseEvent
),需要大量参数,但在大多数情况下,无法完全初始化事件对象的所有属性。因此,继承自基础 Event
接口的事件接口,要求每个派生接口的初始化器都要显式调用,才能完全初始化一个事件。
由于该标准开发周期较长,部分实现可能依赖这些(现已废弃的)初始化方法。为完整性考虑,本文附录描述了这些遗留事件初始化器。
6.1. 遗留事件初始化器接口
本节为说明性内容
本节记录了本规范早期版本引入的遗留初始化方法。
6.1.1. UIEvent 接口初始化器
partial interface UIEvent { // 本规范已废弃undefined initUIEvent (DOMString ,
typeArg optional boolean =
bubblesArg false ,optional boolean =
cancelableArg false ,optional Window ?=
viewArg null ,optional long = 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. MouseEvent 接口初始化器
partial interface MouseEvent { // 本规范已废弃undefined initMouseEvent (DOMString ,
typeArg optional boolean =
bubblesArg false ,optional boolean =
cancelableArg false ,optional Window ?=
viewArg null ,optional long = 0,
detailArg optional long = 0,
screenXArg optional long = 0,
screenYArg optional long = 0,
clientXArg optional long = 0,
clientYArg optional boolean =
ctrlKeyArg false ,optional boolean =
altKeyArg false ,optional boolean =
shiftKeyArg false ,optional boolean =
metaKeyArg false ,optional short = 0,
buttonArg optional EventTarget ?=
relatedTargetArg null ); };
initMouseEvent(typeArg)
-
初始化
MouseEvent
对象的属性。该方法行为与UIEvent.initUIEvent()
相同。initMouseEvent
方法已废弃,但为兼容大量已部署实现仍支持。- DOMString typeArg
- 参见
initEvent()
方法参数说明。 - boolean bubblesArg
- 参见
initEvent()
方法参数说明。 - boolean cancelableArg
- 参见
initEvent()
方法参数说明。 - Window? viewArg
- 指定
view
。该值可以为null
。 - long detailArg
- 指定
detail
。 - long screenXArg
- 指定
screenX
。 - long screenYArg
- 指定
screenY
。 - long clientXArg
- 指定
clientX
。 - long clientYArg
- 指定
clientY
。 - boolean ctrlKeyArg
- 指定
ctrlKey
。 - boolean altKeyArg
- 指定
altKey
。 - boolean shiftKeyArg
- 指定
shiftKey
。 - boolean metaKeyArg
- 指定
metaKey
。 - short buttonArg
- 指定
button
。 - EventTarget? relatedTargetArg
- 指定
relatedTarget
。该值可以为null
。
6.1.3. KeyboardEvent 接口初始化器
该遗留 KeyboardEvent 初始化器的参数列表不包含 detailArg
(其它初始化器有),并新增了
locale
参数;为兼容现有实现必须保留此不一致性。
partial interface KeyboardEvent { // 本规范最初引入(现已废弃)undefined initKeyboardEvent (DOMString ,
typeArg optional boolean =
bubblesArg false ,optional boolean =
cancelableArg false ,optional Window ?=
viewArg null ,optional DOMString = "",
keyArg optional unsigned long = 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.4. CompositionEvent 接口初始化器
该遗留 CompositionEvent 初始化器的参数列表不包含 detailArg
(其它初始化器有),并新增了
locale
参数;为兼容现有实现必须保留此不一致性。
partial interface CompositionEvent { // 本规范最初引入(现已废弃)undefined initCompositionEvent (DOMString ,
typeArg optional boolean =
bubblesArg false ,optional boolean =
cancelableArg false ,optional WindowProxy ?=
viewArg null ,optional DOMString = ""); };
dataArg
initCompositionEvent(typeArg)
-
初始化一个
CompositionEvent
对象的属性。该方法的行为与UIEvent.initUIEvent()
相同。detail
的值保持未定义。initCompositionEvent
方法已废弃。- DOMString typeArg
- 参见
initEvent()
方法参数说明。 - boolean bubblesArg
- 参见
initEvent()
方法参数说明。 - boolean cancelableArg
- 参见
initEvent()
方法参数说明。 - Window? viewArg
- 指定
view
。该值可以为null
。 - DOMString dataArg
- 指定
data
。
7. 传统键盘和鼠标事件属性
本节为非规范性内容。以下属性已废弃,仅应由需要与传统软件兼容的用户代理实现,这些软件需要这些键盘事件。
这些特性从未被正式规范,目前各浏览器的实现存在显著差异。大量传统内容(包括脚本库)依赖于检测用户代理并据此操作,这意味着任何对这些传统属性和事件的正式规范化尝试都可能带来与修复同样多的问题。此外,这些属性不适用于国际化,也未解决可访问性问题。
因此,本规范未对常用于处理键盘输入的事件和属性进行规范性定义,尽管它们可能会在用户代理中出现以兼容传统内容。作者应使用key
属性,而不是charCode
和keyCode
属性。
不过,为了说明这些特性当前的状态及其与规范性事件和属性的关系,本节提供了相关的说明性描述。对于支持这些属性和事件的实现,建议参考本节提供的定义。
7.1. 传统 UIEvent
补充接口
本节为非规范性内容
用户代理通常包含一个which
属性,以便KeyboardEvent
和MouseEvent
可以记录补充事件信息。
以往版本的规范曾在KeyboardEvent
和MouseEvent
上分别定义which
属性,而不是在UIEvent
上定义共享的which
属性。
7.1.1. 接口 UIEvent(补充)
部分UIEvent
接口是对UIEvent
接口的说明性扩展,增加了which
属性。
partial interface UIEvent { // 以下用于支持传统用户代理readonly attribute unsigned long which ; };
which
, 类型为 unsigned long,只读- 对于
MouseEvent
, 包含的值等于button
+1。 对于KeyboardEvent
, 保存与按下的键相关的未修改标识符的系统和实现相关的数值代码。多数情况下,此值与keyCode
相同。
7.1.2. 接口 UIEventInit(补充)
包含对which
的支持的浏览器应在UIEvent
中添加以下成员到UIEventInit
字典。
部分UIEventInit
字典是对UIEventInit
字典的说明性扩展,增加了which
成员用于初始化对应的UIEvent
属性。
partial dictionary UIEventInit {unsigned long which = 0; };
which
, 类型为 unsigned long,默认值为0
- 初始化
which
属性到UIEvent
。
7.2. 传统 KeyboardEvent
补充接口
本节为非规范性内容
浏览器对键盘的支持传统上依赖于三个临时属性:keyCode
、
charCode
,
以及UIEvent
的
which
。
这三个属性均返回表示所按下键的某些方面的数值编码:keyCode
是键自身的索引;charCode
是字符键的 ASCII 值;which
在可用时为字符值,否则为键索引。这些属性的值及是否可用,在不同平台、键盘语言和布局、用户代理、版本甚至事件类型之间均不一致。
7.2.1. 接口 KeyboardEvent(补充)
部分KeyboardEvent
接口是对
KeyboardEvent
接口的说明性扩展,增加了charCode
和keyCode
属性。
部分KeyboardEvent
接口可通过在支持该扩展的实现中调用createEvent()
方法获得。
partial interface KeyboardEvent { // 以下用于支持传统用户代理readonly attribute unsigned long charCode ;readonly attribute unsigned long keyCode ; };
charCode
, 类型为 unsigned long,只读-
charCode
保存字符值,对于生成字符输入的keypress
事件,其值为该字符的 Unicode 编号(例如对于可打印字符event.charCode = event.key.charCodeAt(0)
)。对于keydown
或keyup
事件,charCode
的值为0
。 keyCode
, 类型为 unsigned long,只读-
keyCode
保存与按下的键相关的未修改标识符的系统和实现相关的数值代码。与key
属性不同,可能值的集合未在本规范中规范化。通常,keyCode
的值应代表 ASCII [RFC20][US-ASCII] 或 Windows 1252 [WIN1252] 的十进制编码,但也可以来自其他适当的字符集。无法识别按键时,键值为0
。详见§ 7.3 传统键位模型,了解如何确定
keyCode
的值。
7.2.2. 接口 KeyboardEventInit(补充)
包含对keyCode
和charCode
支持的浏览器应在KeyboardEvent
中添加以下成员到KeyboardEventInit
字典。
部分KeyboardEventInit
字典是对KeyboardEventInit
字典的说明性扩展,增加了charCode
和keyCode
成员用于初始化对应的KeyboardEvent
属性。
partial dictionary KeyboardEventInit { // 以下用于支持传统用户代理unsigned long charCode = 0;unsigned long keyCode = 0; };
charCode
, 类型为 unsigned long,默认值为0
- 初始化
charCode
属性到KeyboardEvent
的对应字符的 Unicode 编码。 keyCode
, 类型为 unsigned long,默认值为0
- 初始化
keyCode
属性到KeyboardEvent
的系统和实现相关的未修改标识符的数值代码。
7.3. 传统键位模型
本节为非规范性内容
不同实现会为不同事件类型暴露这些属性的不同值。实现可以选择在keyCode
属性中同时暴露虚拟键码和字符码(混合模型),或者分别报告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用户代理需要判断是否要根据该click
事件的默认行为合成一个具有相同相关属性的DOMActivate
事件。判断线索可能包括click
事件的isTrusted
属性,或其事件目标是否已注册DOMActivate
事件监听器。
不要依赖于多数DOMActivate
在众多用户代理中的互操作支持。应使用click
事件类型,因其更广泛的实现支持能带来更好的可访问性。
DOMActivate
事件类型在本规范中已被弃用。
8.1.2. 激活事件顺序
如果用户代理支持DOMActivate
事件,则事件必须按如下顺序分发(仅列出相关事件):
事件类型 | 备注 | |
---|---|---|
1 | click
| |
2 | DOMActivate
| 默认行为,如用户代理支持;合成;isTrusted="true"
|
3 | 所有其他默认行为,包括激活行为 |
如果通过按键事件激活焦点元素,则如下为典型事件顺序(仅列出相关事件):
事件类型 | 备注 | |
---|---|---|
1 | keydown
| 必须是可激活元素的按键,如Enter 或 (空格键),否则元素不会被激活
|
2 | click
| 默认行为;合成;isTrusted="true"
|
3 | DOMActivate
| 默认行为,如用户代理支持;合成;isTrusted="true"
|
4 | 所有其他默认行为,包括激活行为 |
8.2.
传统 FocusEvent
事件
8.2.1.
传统 FocusEvent
事件类型
8.2.1.1. DOMFocusIn
类型 | DOMFocusIn
|
---|---|
接口 | FocusEvent
|
同步 / 异步 | 同步 |
冒泡 | 是 |
可信目标 | Window , Element
|
可取消 | 否 |
可组合 | 是 |
默认行为 | 无 |
上下文 (可信事件) |
|
当用户代理的事件目标获得焦点时,必须分发此事件。必须在分发此事件类型之前将焦点赋予该元素。此事件类型必须在focus
事件类型之后分发。
DOMFocusIn
事件类型在本规范中仅为参考和完整性定义,但本规范弃用了该事件类型,建议使用相关的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
事件通常用于检测字符值而不是物理按键,因此某些配置下并非所有按键都能触发该事件。
keypress
事件类型在本规范中定义仅供参考和完整性考虑,但本规范弃用该事件类型。在编辑场景中,作者应订阅beforeinput
事件。
8.3.2.
keypress
事件顺序
keypress
事件类型必须在keydown
事件之后、与同一按键相关的keyup
事件之前派发。
keypress
事件类型必须在beforeinput
事件之后、与同一按键相关的input
事件之前派发。
支持keypress
事件的用户代理的按键事件顺序如下示例:
事件类型 | KeyboardEvent key
| InputEvent data
| 备注 | |
---|---|---|---|---|
1 | keydown
| "a"
| ||
2 | beforeinput
| "a"
| ||
3 | keypress
| "a"
| ||
与此按键相关的任何默认行为,如插入字符到DOM等。 | ||||
4 | input
| |||
5 | keyup
| "a"
|
8.4.
传统TextEvent
事件
[Exposed =Window ]interface :
TextEvent UIEvent {readonly attribute DOMString ;
data undefined (
initTextEvent DOMString ,
type optional boolean =
bubbles false ,optional boolean =
cancelable false ,optional Window ?=
view null ,optional DOMString = "undefined"); };
data
参见UI Events 算法的文本事件部分,了解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 或标准文档中的类似定义。更多信息请参见定义中的链接。
- 激活触发器
-
定义为启动激活行为的事件。
- 作者
-
在本规范上下文中,作者、内容作者或脚本作者是指编写脚本或其他可执行内容、并使用本规范定义的接口、事件和事件流的人。详见§ 1.2.3 内容作者与内容 的一致性类别。
- body 元素
-
在 HTML 或 XHTML 文档中,body 元素表示文档内容。在结构良好的 HTML 文档中,body 元素是根元素的第一个子元素。
- 字符值
-
在键值上下文中,字符值是表示一个或多个 Unicode 字符(如字母或符号,或一组字母)的字符串,每个字符属于有效Unicode 字符类别集合。本规范中,字符值以 unicode 字符串(如
U+0020
)或相同码点的字形表示(如" "
)来表示,并用颜色区分这两种表示方式。在源代码中,一些键值(如非可视字符)可用所用编程语言的字符转义语法表示。
- 死键
-
死键是一种键或组合键,本身不产生字符,但与其它键组合或顺序按下时可产生带变音符号的字符(如
"ö"
、"é"
、"â"
)。 - 默认行为
-
默认行为是实现必须与事件对象的派发一起执行的可选补充行为。每个事件类型的定义及规范都会定义该事件类型的默认行为(如有)。某些情况下,一个事件实例可能有多个默认行为,如与激活触发器相关时。默认行为可通过调用
preventDefault()
方法取消。 - delta
-
用户代理响应支持
WheelEvent
接口(如鼠标滚轮或触摸板)的输入设备物理移动,估算页面滚动或缩放的量(以像素、行或页为单位)。delta的值(如deltaX
、deltaY
或deltaZ
属性)应结合当前deltaMode
属性解读。滚轮(或其他设备)物理移动与delta正负号的关系依环境和设备而异。但如用户代理以默认行为滚动,则delta的符号按右手坐标系定义,X、Y、Z 轴正方向分别指向文档最右边、最下边、和最远(远离用户)深度。 - 弃用
-
被标记为弃用的功能仅为兼容旧实现或规范而保留,在本规范中是可选且不推荐的。只有已有或正在替代的功能才会在本规范中弃用。尚未支持该功能的实现可为兼容现有内容而实现弃用功能,但内容作者新建内容时不应使用弃用功能,除非无其他解决方案。引用本规范的其他规范不应使用弃用功能,应转而引用其替代方案。被弃用的功能预计将在未来规范中被移除。
- 空字符串
-
空字符串是长度为
0
的DOMString
类型值,即不包含任何字符(无打印字符也无控制字符)的字符串。 - 事件焦点
-
事件焦点是对文档中特定元素或其它事件目标的特殊接收与集中状态。每个元素在获得焦点时行为不同,取决于其功能,如激活准备(按钮或链接)、切换状态(复选框)、接收文本输入(文本表单域)或复制选中文本。详见§ 3.3.3 文档焦点与焦点上下文。
- 事件焦点环
-
事件焦点环是文档中一组有序的事件焦点目标。宿主语言可定义一种或多种目标排序方式,如文档顺序、每个焦点目标的数值索引、焦点目标间的显式指针或多种模型的混合。每个文档可包含多个焦点环或条件焦点环。通常,文档顺序或索引型焦点环会使焦点从最后一个目标“环回”到第一个目标。
- 事件目标
- 事件类型
-
事件类型是具有特定名称的事件对象,定义了具体触发条件、属性及其它区分于其他事件类型的特征。例如,
click
事件类型与mouseover
或load
事件类型特征不同。事件类型通过事件对象上的type
属性暴露。也可泛称为“事件”,如click
事件。 - 宿主语言
-
集成其它语言或 API 规范特性,同时规范性引用原规范而非重定义这些特性,并仅按原规范定义方式扩展这些特性的语言。原规范通常仅打算在一个或多个宿主语言上下文中实现,而非作为独立语言。例如,XHTML、HTML 和 SVG 都是 UI Events 的宿主语言,集成并扩展本规范定义的对象和模型。
- 迟滞
-
人机界面设计中的一个特性,允许输入值在一定位置或时间范围内被接受,以提升用户体验。例如,允许用户双击鼠标按钮的时间略有偏差属于时间迟滞,用户从父窗口鼠标移出到子菜单时不立即关闭嵌套菜单属于位置迟滞。
- IME
- 输入法编辑器
-
输入法编辑器(IME),也称前端处理器,是一种应用程序,负责将键盘输入转换为表意文字或其它字符,通常通过用户引导的词典查找实现,常用于东亚语言(如中文、日文、韩文)。IME也可用于基于词典的单词补全,如移动设备。有关 IME 的规范处理,参见§ 4.3.3 输入法编辑器。另见文本输入系统。
- 按键映射
-
按键映射是为特定按键分配键值的过程,结果受多种因素影响,包括操作系统和键盘布局(如QWERTY、Dvorak、西班牙语、InScript、中文等),以及所有修饰键(
Shift
、Alt
等)和死键状态。 - 按键值
-
按键值是字符值或多字符字符串(如
"Enter"
、"Tab"
或"MediaTrackNext"
),对应于特定状态下的按键。每个按键都有按键值,无论其是否有字符值,包括控制键、功能键、修饰键、死键及其它按键。任意按键在任意时刻的按键值取决于按键映射。 - 修饰键
-
修饰键改变按键的正常行为,如输出不同大小写字符(如
Shift
键)、或改变按键触发的功能(如Fn
或Alt
键)。详见§ 4.3.1 修饰键及修饰键表,可查阅所有有效修饰键。 - 命名空间 URI
-
命名空间 URI是标识 XML 命名空间的 URI。在[XML-Names11]中称为命名空间名称。有关 URI 及命名空间 URI 在 DOM API 中的处理与比较,详见第 1.3.2 节DOM URI和第 1.3.3 节XML 命名空间。
- QWERTY
-
QWERTY(发音为
ˈkwɜrti
)是一种常见键盘布局,因字母键顶行前五个字符键为 Q、W、E、R、T、Y 而得名。还有许多其他流行键盘布局(如 Dvorak、Colemak),多数为本地化或人体工学设计。 - 根元素
-
文档中的第一个元素节点,所有其他元素都是其子元素。即文档元素。
- 旋转
-
使用
WheelEvent
接口的输入设备上的增量变化指示。在某些设备上可能是轮的实际旋转,或在其他设备上为平面上的移动,或对特定按钮的压力。 - 文本输入系统
-
将某种替代输入(如输入法编辑器、语音处理器或手写识别系统)解释并转换为文本的软件组件。
- 最顶层事件目标
-
最顶层事件目标必须是渲染顺序中最高、且能成为事件目标的元素。在图形界面中即为用户指针设备下的元素。用户界面的
命中测试
用于确定目标。有关命中测试和堆叠顺序的细节,见宿主语言。 - Unicode 字符类别
-
为每个 Unicode 码点定义的一般类别值的子集。该子集包含所有 字母(Ll、Lm、 Lo、Lt、Lu)、 数字(Nd、Nl、 No)、 标点(Pc、Pd、 Pe、Pf、 Pi、Po、 Ps) 和符号(Sc、Sk、 Sm、So) 类别值。
- 未初始化值
-
事件属性(如
bubbles
或currentTarget
)在事件用initEvent()
初始化前的值。事件的未初始化值在用createEvent()
方法新建事件后立即生效。