13.4.4 键盘与文本事件
优质
小牛编辑
131浏览
2023-12-01
用户在使用键盘时会触发键盘事件。“DOM2 级事件”最初规定了键盘事件,但在最终定稿之前又删除了相应的内容。结果,对键盘事件的支持主要遵循的是DOM0 级。 “DOM3 级事件”为键盘事件制定了规范,IE9 率先完全实现了该规范。其他浏览器也在着手实现这一标准,但仍然有很多遗留的问题。 有3 个键盘事件,简述如下。
- keydown:当用户按下键盘上的任意键时触发,而且如果按住不放的话,会重复触发此事件。
- keypress:当用户按下键盘上的字符键时触发,而且如果按住不放的话,会重复触发此事件。
- keyup:当用户释放键盘上的键时触发。
键盘事件与鼠标事件一样,都支持相同的修改键。而且,键盘事件的事件对象中也有shiftKey、ctrlKey、altKey 和metaKey 属性。IE 不支持metaKey。
1. 键码
在发生keydown 和keyup 事件时,event 对象的keyCode 属性中会包含一个代码,与键盘上一个特定的键对应。对数字字母字符键,keyCode 属性的值与ASCII 码中对应小写字母或数字的编码相同。因此,数字键7 的keyCode 值为55,而字母A 键的keyCode 值为65——与Shift 键的状态无关。 DOM 和IE 的event 对象都支持keyCode 属性。请看下面这个例子:var textbox = document.getElementById("myText"); EventUtil.addHandler(textbox, "keyup", function(event) { event = EventUtil.getEvent(event); alert(event.keyCode); });运行一下 在这个例子中,用户每次在文本框中按键触发keyup 事件时,都会显示keyCode 的值。下表列出了所有非字符键的键码。无论keydown 或keyup 事件都会存在的一些特殊情况。在Firefox 和Opera 中,按分号键时keyCode值为59,也就是ASCII 中分号的编码;但IE 和Safari 返回186,即键盘中按键的键码。
2. 字符编码
发生keypress 事件意味着按下的键会影响到屏幕中文本的显示。在所有浏览器中,按下能够插入或删除字符的键都会触发keypress 事件;按下其他键能否触发此事件因浏览器而异。由于截止到2008年,尚无浏览器实现“DOM3 级事件”规范,所以浏览器之间的键盘事件并没有多大的差异。 IE9、Firefox、Chrome 和Safari 的event 对象都支持一个charCode 属性,这个属性只有在发生keypress 事件时才包含值,而且这个值是按下的那个键所代表字符的ASCII 编码。此时的keyCode通常等于0 或者也可能等于所按键的键码。IE8 及之前版本和Opera 则是在keyCode 中保存字符的ASCII编码。要想以跨浏览器的方式取得字符编码,必须首先检测charCode 属性是否可用,如果不可用则使用keyCode,如下面的例子所示。var EventUtil = { //省略的代码 getCharCode: function(event) {if (typeof event.charCode == "number") {return event.charCode;} else {return event.keyCode;} }, //省略的代码 };这个方法首先检测charCode 属性是否包含数值(在不支持这个属性的浏览器中,值为undefined),如果是,则返回该值。否则,就返回keyCode 属性值。下面是使用这个方法的示例。
var textbox = document.getElementById("myText"); EventUtil.addHandler(textbox, "keypress", function(event) { event = EventUtil.getEvent(event); alert(EventUtil.getCharCode(event)); });运行一下 在取得了字符编码之后,就可以使用String.fromCharCode()将其转换成实际的字符。
3. DOM3 级变化
尽管所有浏览器都实现了某种形式的键盘事件,DOM3 级事件还是做出了一些改变。比如,DOM3级事件中的键盘事件,不再包含charCode 属性,而是包含两个新属性:key 和char。 其中,key 属性是为了取代keyCode 而新增的,它的值是一个字符串。在按下某个字符键时,key的值就是相应的文本字符(如“k”或“M”);在按下非字符键时, key 的值是相应键的名(如“Shift”或“Down”)。而char 属性在按下字符键时的行为与key 相同,但在按下非字符键时值为null。 IE9 支持key 属性,但不支持char 属性。Safari 5 和Chrome 支持名为keyIdentifier 的属性,在按下非字符键(例如Shift)的情况下与key 的值相同。对于字符键,keyIdentifier 返回一个格式类似“U+0000”的字符串,表示Unicode 值。var textbox = document.getElementById("myText"); EventUtil.addHandler(textbox, "keypress", function(event) { event = EventUtil.getEvent(event); var identifier = event.key || event.keyIdentifier; if (identifier) {alert(identifi er); } });运行一下 由于存在跨浏览器问题,因此本书不推荐使用key、keyIdentifier 或char。 DOM3 级事件还添加了一个名为location 的属性,这是一个数值,表示按下了什么位置上的键: 0 表示默认键盘,1 表示左侧位置(例如左位的Alt 键),2 表示右侧位置(例如右侧的Shift 键),3 表示数字小键盘,4 表示移动设备键盘(也就是虚拟键盘),5 表示手柄(如任天堂Wii 控制器)。IE9 支持这个属性。Safari 和Chrome 支持名为keyLocation 的等价属性,但即有bug——值始终是0,除非按下了数字键盘(此时,值 为3);否则,不会是1、2、4、5。
var textbox = document.getElementById("myText"); EventUtil.addHandler(textbox, "keypress", function(event) { event = EventUtil.getEvent(event); var loc = event.location || event.keyLocation; if (loc) {alert(loc); } });运行一下 与key 属性一样,支持location 的浏览器也不多,所以在跨浏览器开发中不推荐使用。 最后是给event 对象添加了getModifierState()方法。这个方法接收一个参数,即等于Shift、Control、AltGraph 或Meta 的字符串,表示要检测的修改键。如果指定的修改键是活动的(也就是处于被按下的状态),这个方法返回true,否则返回false。
var textbox = document.getElementById("myText"); EventUtil.addHandler(textbox, "keypress", function(event) { event = EventUtil.getEvent(event); if (event.getModifierState) {alert(event.getModifierState("Shift")); } });运行一下 实际上,通过event 对象的shiftKey、altKey、ctrlKey 和metaKey 属性已经可以取得类似的属性了。IE9 是唯一支持getModifierState()方法的浏览器。
4. textInput 事件
“DOM3 级事件”规范中引入了一个新事件,名叫textInput。根据规范,当用户在可编辑区域中输入字符时,就会触发这个事件。这个用于替代keypress 的textInput 事件的行为稍有不同。区别之一就是任何可以获得焦点的元素都可以触发keypress 事件,但只有可编辑区域才能触发textInput事件。区别之二是textInput 事件只会在用户按下能够输入实际字符的键时才会被触发,而keypress事件则在按下那些能够影响文本显示的键时也会触发(例如退格键)。 由于textInput 事件主要考虑的是字符,因此它的event 对象中还包含一个data 属性,这个属性的值就是用户输入的字符(而非字符编码)。换句话说,用户在没有按上档键的情况下按下了S 键,data 的值就是"s",而如果在按住上档键时按下该键,data 的值就是"S"。 以下是一个使用textInput 事件的例子:var textbox = document.getElementById("myText"); EventUtil.addHandler(textbox, "textInput", function(event) { event = EventUtil.getEvent(event); alert(event.data); });运行一下 在这个例子中,插入到文本框中的字符会通过一个警告框显示出来。另外,event 对象上还有一个属性,叫inputMethod,表示把文本输入到文本框中的方式。
- 0,表示浏览器不确定是怎么输入的。
- 1,表示是使用键盘输入的。
- 2,表示文本是粘贴进来的。
- 3,表示文本是拖放进来的。
- 4,表示文本是使用IME 输入的。
- 5,表示文本是通过在表单中选择某一项输入的。
- 6,表示文本是通过手写输入的(比如使用手写笔)。
- 7,表示文本是通过语音输入的。
- 8,表示文本是通过几种方法组合输入的。
- 9,表示文本是通过脚本输入的。