此文是W3C UI Events标准的阅读笔记。UI Events是一些列预定好的[DOM]事件,主要用来跟用户交互。
W3C UI Events阅读笔记
事件类型
输入事件(Input Events)
输入事件是指DOM被用户操作修改之后所发送的通知。定义如下:
[Constructor(DOMString type, optional InputEventInit eventInitDict), Exposed=Window]
interface InputEvent : UIEvent {
readonly attribute DOMString? data;
readonly attribute boolean isComposing;
readonly attribute DOMString inputType;
};
- data存储这输入法产生的数据
- isComposing用来指示当前的输入法拼接过程是否结束
- inputType用来指示输入的类型,见Input Events Level 1
输入事件只有两种:
- beforeinput
- input
键盘事件(Keyboard Events)
键盘事件跟设备相关(这里的设备大概就是指键盘咯)。它们依赖于操作系统如果处理键盘事件。通常操作系统会指定和识别若干种预置类型的键盘,然后键盘厂商通过驱动去匹配这些键盘类型。除此之外,操作系统又会根据区域语言的不同,来对一种硬盘类型使用不同的键盘映射表。这里面有两层抽象,键盘产生的是扫描码,然后操作系统将扫描码转换成虚拟码。一种键盘类型规定了这个键盘会产生什么样的扫描码,而键盘映射表则决定如果将这些扫描码转化成虚拟码。最终应用程序接收到的是虚拟码。
键盘事件定义:
[Constructor(DOMString type, optional KeyboardEventInit eventInitDict), Exposed=Window]
interface KeyboardEvent : UIEvent {
// KeyLocationCode
const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00;
const unsigned long DOM_KEY_LOCATION_LEFT = 0x01;
const unsigned long DOM_KEY_LOCATION_RIGHT = 0x02;
const unsigned long DOM_KEY_LOCATION_NUMPAD = 0x03;
readonly attribute DOMString key;
readonly attribute DOMString code;
readonly attribute unsigned long location;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute boolean repeat;
readonly attribute boolean isComposing;
boolean getModifierState(DOMString keyArg);
};
解释一卡其中的某些字段:
- key用来区分键盘码(就是键盘上的按键),而code用来区分虚拟码(按键产生的值)。一个虚拟码,比如ALT,可以由左ALT键产生,也可以由右ALT键产生。location可以用来区分具体键的位置。
- repeat表明键被按住,然后不断发送虚拟码,每次会按顺序产生三个事件keydown, beforeinput, input
- isComposing表明输入法正在合成字符
默认情况下键的location必须是DOM_KEY_LOCATION_STANDARD。对于其他一些键,它们的值可以在两个地方出现,这些键定义如下:
- “Shift”, “Control”, “Alt”, “Meta"的location可以是DOM_KEY_LOCATION_LEFT, DOM_KEY_LOCATION_RIGHT
- “ArrowDown”, “ArrowLeft”, “ArrowRight”, “ArrowUp"的location可以是DOM_KEY_LOCATION_STANDARD, DOM_KEY_LOCATION_NUMPAD
- “End”, “Home”, “PageDown”, “PageUp"的location可以是DOM_KEY_LOCATION_STANDARD, DOM_KEY_LOCATION_NUMPAD
- “0”, “1”, “2”, “2”, “4”, “5”, “6”, “7”, “8”, “9”, “.”, “Enter”, “+”, “-”, “*”, “/“的location可以是DOM_KEY_LOCATION_STANDARD, DOM_KEY_LOCATION_NUMPAD
可以看到,UIEvents试图将具体键所在的位置暴露给上层的应用程序。
键盘事件类型只有两种:
- keydown
- keyup
敲击一个按键输入的时候,事件系列如下:
- keydown
- beforeinput (只有能够产生字符的键才有此事件)
- input(只有字符被插入DOM时才产生这个事件)
- keyup
如果按住一个按键,会持续产生以下事件序列:
- keydown
- beforeinput(只有能够产生字符的键才有此事件)
- input(只有字符被插入DOM时才产生这个事件)
字符合成事件(Composition Events)
有一些字符不在键盘默认可以产生的字符集合之中,针对这种情况,操作系统需要使用一些辅助措施,比如使用键盘映射,或者输入法来解决这个问题。键盘映射的例子,macos下按ALT+P可以产生一个π
字符;对于输入法,大家都很熟悉了,中文就是使用输入法输入的。
字符合成事件的定义:
[Constructor(DOMString type, optional CompositionEventInit eventInitDict), Exposed=Window]
interface CompositionEvent : UIEvent {
readonly attribute DOMString data;
};
使用输入法合成事件的时候,通常会产生以下事件:
- compositionstart表示开始合成
- compositionupdate表示合成过程中的更新
- compositionend表示此次合成结束,也就是按了回车,字符输入
字符合成事件不止可以用于输入法,也可以用于手写输入设备,下面是一个例子
- compositionstart,开始识别,数据为空
- compositionupdate,产生候选列表,最佳匹配“test”,数据为“test”
- compositionupdate,用户不选择最佳匹配,而选择了“text”,数据为“text”
- compositionend,识别结束,数据为“text”
compositionstart是在用户敲击键盘的时候产生的,所以在compositionstart之前会先产生一个keydown事件。如果这个keydown事件被取消,那么后续的合成事件不会派发。另外一种情况是,如果compositionstart事件本身被中止,那么应该立马产生一个compositionend事件来中止事件合成过程。
字符合成过程是和键盘事件交织在一起的:
- keydown
- compositionstart(进入合成状态)
- compositionupdate
- keyup
- ……
- keydown
- compositionend((退出合成状态)
- keyup
字符合成过程也是和输入事件交织子啊一起的:
- beforeinput
- compositionupdate
- (DOM更新)
- input
- compositionend
键盘事件和虚拟码
5. Keyboard events and key values
当键盘上的一个键其实蕴含了很多信息:
- 机械相关的信息:按键的尺寸、位置
- 按键的直观标识:比如H键上的H就是个标识,但是按下H键一定会产生H字符吗?
- 按键生成的键码:按键产生的虚拟码,按下H键所产生的H字符
按下一个键,然后最后产生的字符的过程有如此大的不确定性。一个浏览器不可能要求所有的键盘长什么样,有什么样的布局,所以UIEvents通过下面两个文档描绘了一个键盘应该是什么样的,支持什么键;剩下的就交给浏览器和操作系统去处理了:
为了区分一个按键的输出属性和物理属性,一个按键会产生两种值,分别是:Key和Code。Key代表的是一个键按下的输出,而Code代表的是布局相关的物理属性,下面是例子:
- US键盘按下”'“之后,产生key是”'",code是"Quote”
- Japanese按下”:“之后,产生key是”:",code是"Quote”
- US Intl按下"Dead"之后,产生的key是"Dead”,code"Quote"
code值可以看成具体的物理键盘布局到一个理想键盘布局的映射,这样可以提供一层抽象,避免应用程序去处理具体的键盘布局。
keycode.info是一个网页,可以显示Javascript的击键信息。
其他参考
- Editing Taskforce
- https://en.wikipedia.org/wiki/Modifier_key
- https://en.wikipedia.org/wiki/AltGr_key
- https://en.wikipedia.org/wiki/Dead_key
- https://en.wikipedia.org/wiki/Compose_key
- https://en.wikipedia.org/wiki/Precomposed_character
- https://developer.mozilla.org/en-US/docs/Web/API/Event/composed
- https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath
(完)