盒子
盒子
文章目录
  1. Javascript键盘事件

JavaScript键盘事件

Javascript键盘事件

  • keydown和keyup事件(低级事件),当用户在键盘上按下或者释放按键时,会发生keydown和keyup事件。它们由辅助键、功能键和字母键产生,如果用户按键时间足够长会导致它开始重复,那么keyup事件到达之前会收到多个keydown事件。
    • 事件对象有个数字属性keyCode,对于可打印字符,keyCode值时按键上出现的字符的Unicode编码。对于字母键,无论是否开启大写,总是返回大写的keyCode,数字键盘也一样,对于是否按下shift,返回的总是一样的。
    • 事件对象有altKey、ctrKey、metaKey、shiftKey属性,当对应的辅助键被按下,它们会被设置为true。
    • 3级dom事件草案,定义了新的事件对象属性key,它会以字符串的形式包含键名。如果是可打印字符,key属性仅仅是这个打印字符,如果是功能键,则会类似’F2’、’Home’、’Left’这样子的值。
  • keypress事件(较高级事件),它表示产生了一个可打印字符,表示输入的单个字符,以数字Unicode编码的形式,所以必须用String.fromCharCode()把它转换成字符串。
    • 大多数浏览器,事件对象的keyCode属性指定了输入的字符编码。可用var char = String.fromCharCode( event.keyCode )获取字符。但是firefox使用的是charCode属性,获取字符需要var char = String.fromCharCode( event.charCode ),而且在firefox中,产生非打印字符时也触发keypress事件(大多数浏览器只有产生了可打印字符时,触发keypress事件),所以为了区分这种情况,可用存在charCode属性,但是值为0做检测。
  • textinput事件(高级事件),3级DOM事件规范草案定义,不管来源(例如:键盘、黏贴、或拖放形式的数据传输、亚洲语言输入法、声音或手写识别系统),无论何时用户输入文本时,都会触发。textinput事件尚未得到支持,但Webkit浏览器支持非常类似的textInput事件。规范的textinput事件和Webkit的textInput事件都有相似的事件对象:
    • 事件对象有一个data属性,用于保存输入的文本。
    • 事件对象的inputMethod属性,用于指定输入源,不过尚未实现。

可通过取消textinput、textInput、和keypress事件来阻止字符的输入。一个例子,用来过滤用户输入

例1-1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
*InputFilter.js:不唐突地过滤<input>元素的键盘输入
*
*这个模块查找文档中拥有"data-allowed-chars"属性的所有<input type="text">元素
*它为所有这类元素都注册keypress、textInput和textinput事件处理程序,
“*来限制用户只能输入出现在许可属性值中的字符
*如果<input>元素也有一个"data-messageid"属性,
*那么认为这个值是另一个文档元素的id
*如果用户输入了不允许的字符,那么会显示消息元素
*如果用户输入了允许的字符,那么会隐藏消息元素
*这个信息id元素用于向用户说明拒绝输入的原因
*它通常应该由CSS控制样式,所以它开始不可见
*
*下面是使用这个模块的HTML代码示例
*邮政编码:<input id="zip"type="text"
*data-allowed-chars="0123456789"data-messageid="zipwarn">
*<span id="zipwarn"style="color:red;visibility:hidden">只支持数字</span>
*
*这个模块相当地不唐突,它没有定义全局命名空间中的任何符号
*/
whenReady(function() { //当文档加载完毕时,运行这个函数
//查找所有<input>元素
var inputelts = document.getElementsByTagName("input"); //遍历它们
for (var i = 0; i< inputelts.length; i++) {
var elt = inputelts[i]; //跳过不是文本域或没有data-allowed-chars属性的元素
if (elt.type != "text" || !elt.getAttribute("data-allowed-chars"))
continue;
//在input元素上注册事件处理程序函数
//传统的keypress事件处理程序能够在任何地方运行
//textInput(混合大小写)在2010年后Safari和Chrome支持
//textinput(小写)是3级DOM事件规范草案中的版本
if (elt.addEventListener) {
elt.addEventListener("keypress", filter, false);
elt.addEventListener("textInput", filter, false);
elt.addEventListener("textinput", filter, false);
} else { //不支持addEventListener()的IE也不会支持textinput
elt.attachEvent("onkeypress", filter);
}
}
//这是用于过滤用户输入的keypress、textInput和textinput事件处理程序
function filter(event) { //获取事件对象和目标元素对象
var e = event || window.event; //标准或IE模型
var target = e.target || e.srcElement; //标准或IE模型
var text = null; //输入的文本
//获取输入的字符或文本
if (e.type === "textinput" || e.type === "textInput") text = e.data;
else { //这是传统的keypress事件
//对于可打印键的keypress事件,Firefox使用charCode
var code = e.charCode || e.keyCode; //如果按下的是任何形式的功能键,不要过滤它
if (code< 32 || //ASCII控制字符
e.charCode == 0 || //功能键(仅指Firefox)
e.ctrlKey || e.altKey) //按下辅助键
return; //不过滤这个事件
//把字符编码转化为字符串
var text = String.fromCharCode(code);
}
//现在需要从input元素中寻找所需信息
var allowed = target.getAttribute("data-allowed-chars"); //合法字符
var messageid = target.getAttribute("data-messageid"); //信息元素id
if (messageid) //如果存在消息元素id,那么获取这个元素
var messageElement = document.getElementById(messageid); //遍历输入文本中的字符
for (var i = 0; i< text.length; i++) {
var c = text.charAt(i);
if (allowed.indexOf(c) == -1) { //这是不允许的字符吗?
//如果存在不合法字符,显示消息元素
if (messageElement) messageElement.style.visibility = "visible"; //取消默认行为,所有不会插入文本
if (e.preventDefault) e.preventDefault();
if (e.returnValue) e.returnValue = false;
return false;
}
}
//如果所有的字符都合法,隐藏存在的消息元素
if (messageElement) messageElement.style.visibility = "hidden";
}
});

keypress和textinput事件是在新输入的文本真正插入到聚焦的文档元素前触发,所以这些事件处理程序能够取消事件和组织文本插入。

  • 浏览器也实现了在文本插入到元素后才触发的input事件类型input。虽然这些事件不能取消,不能指定事件对象中的最新文本,但它们能以某种形式提供元素文本内容发生改变的通知。例如,想确保输入框中输入的任何文本都是大写的,可以,例1-2:姓氏:<input type="text"oninput="this.value=this.value.toUpperCase();">

    • html5标准化了input,除IE外的浏览器都支持它。在IE中,可以使用不标准的propertychange事件检测文本输入元素的value属性改变来实现相似的效果。

      使用propertychange事件探测文本输入

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      function forceToUpperCase(element) {
      if (typeof element === "string") element = document.getElementById(element);
      element.oninput = upcase;
      element.onpropertychange = upcaseOnPropertyChange; //简易案例:用于input事件的处理程序
      function upcase(event) {
      this.value = this.value.toUpperCase();
      }
      //疑难案例:用于propertychange事件的处理程序
      function upcaseOnPropertyChange(event) {
      var e = event || window.event; //如果value属性发生改变
      if (e.propertyName === "value") { //移除onpropertychange处理程序,避免循环调用
      this.onpropertychange = null; //把值都变成大写
      this.value = this.value.toUpperCase(); //然后恢复原来的propertychange处理程序
      this.onpropertychange = upcaseOnPropertyChange;
      }
      }
      }

参考资料:

《JavaScript权威指南》第六版 p670

keydown, keypress, keyup

使用中文输入法时对键盘事件的处理

支持一下
扫一扫,支持lcoder