在JavaScript中监听IME键盘输入事件


Posted in Javascript onMay 29, 2011

输入法应当如何触发键盘事件呢?是每一下击键都触发一次事件,还是选词完毕才触发事件呢?整句输入又该如何触发事件呢?不同的操作系统和不同的浏览器对此有不同的看法。在最糟糕的情况下,用户使用输入法后浏览器就只触发一次 keydown ,之后就没有任何的键盘事件了。这对于 Suggestion 控件的实现来说是个大问题,因为 Suggestion 控件需要监听文本输入框的变化,而事件是最准确也最节省计算资源的做法,如果换成轮询的话性能就可能受到影响。
首先,要监听启用输入法后的击键事件应当使用 keydown 事件,这是信息最丰富的一个事件,因为在启用输入法后别的键盘事件可能不会被触发。其次,大多数操作系统和浏览器都实现了一个事实标准,就是在用户使用输入法输入时, keydown 事件传入的 keyCode 取值为 229 。然而触发 keydown 的频率是不确定的,有些情况下每一下击键都触发事件,有些情况下只有选词完毕才触发事件。这时候,如果我们还是要实时监控文本框的内容变化,就必须使用轮询了。

var timer; 
var imeKey = 229; 
function keydownHandler (e) { 
clearInterval(timer) 
if (e.keyCode == imeKey) { 
timer = setInterval(checkTextValue, 50); 
} else { 
checkTextValue(); 
} 
} 
function checkTextValue() { 
/* handle input text change */ 
}

Opera 是一款有趣的浏览器,别人做的事情它都不做,别人都不做的事情它都喜欢做。例如说,它偏偏不支持 keyCode == 229 这个事实标准,而要使用 keyCode == 197 来表示输入法的使用。因此,你需要在上述代码的基础上做一下改良,如果监测到是 Opera 浏览器,就换一个 keyCode 常量来做比较。
var imeKey = (UA.Opera == 0) ? 229 : 197;
最后,还有一个更不受重视的浏览器叫做 Firefox for Mac 。估计是因为 Mac 版本对于 Mozilla 来说实在是太不重要了,所以很多 Windows 版本都没问题的地方 Mac 版本就会出小问题,例如说对上述事件的支持。 Firefox for Mac 不会出现 keyCode == 229 的情况,而且在输入法启用后只有第一下击键会触发 keydown 事件,因此只能在击键后一直使用轮询。
if (e.keyCode == imeKey || UA.Firefox > 0 && UA.OS == 'Macintosh') {
在添加了这两项改进后,实时监控文本框的变化就没有问题了,即使用户启用了输入法。完整的代码如下:
var timer; 
var imeKey = (UA.Opera == 0) ? 229 : 197; 
function keydownHandler (e) { 
clearInterval(timer) 
if (e.keyCode == imeKey || UA.Firefox > 0 && UA.OS == 'Macintosh') { 
timer = setInterval(checkTextValue, 50); 
} else { 
checkTextValue(); 
} 
} 
function checkTextValue() { 
/* handle input text change */ 
}
Javascript 相关文章推荐
jquery 循环显示div的示例代码
Oct 18 Javascript
Enter转换为Tab的小例子(兼容IE,Firefox)
Nov 14 Javascript
escape函数解决js中ajax传递中文出现乱码问题
Oct 30 Javascript
JScript中的条件注释详解
Apr 24 Javascript
javascript多行字符串的简单实现方式
May 04 Javascript
Jquery和JS获取ul中li标签的实现方法
Jun 02 Javascript
AngularJS+bootstrap实现动态选择商品功能示例
May 17 Javascript
解决ionic和angular上拉加载的问题
Aug 03 Javascript
vue2.0 computed 计算list循环后累加值的实例
Mar 07 Javascript
详解VUE中常用的几种import(模块、文件)引入方式
Jul 03 Javascript
vue实现搜索过滤效果
May 28 Javascript
vue webpack build资源相对路径的问题及解决方法
Jun 04 Javascript
解读JavaScript代码 var ie = !-[1,] 最短的IE判定代码
May 28 #Javascript
Jquery css函数用法(判断标签是否拥有某属性)
May 28 #Javascript
最新28个很棒的jQuery 教程
May 28 #Javascript
JavaScript使用IEEE 标准进行二进制浮点运算产生莫名错误的解决方法
May 28 #Javascript
真正的JQuery.ajax传递中文参数的解决方法
May 28 #Javascript
jquery 图片上传按比例预览插件集合
May 28 #Javascript
使用jquery实现select添加实现后台权限添加的效果
May 28 #Javascript
You might like
PHP中将字符串转化为整数(int) intval() printf() 性能测试
2020/03/20 PHP
ThinkPHP模板引擎之导入资源文件方法详解
2014/06/18 PHP
PHP获取用户访问IP地址的5种方法
2016/05/16 PHP
利用PHP自动生成印有用户信息的名片
2016/08/01 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
PHP使用XMLWriter读写xml文件操作详解
2018/07/31 PHP
php进程(线程)通信基础之System V共享内存简单实例分析
2019/11/09 PHP
html下载本地
2006/06/19 Javascript
syntaxhighlighter 使用方法
2007/07/02 Javascript
javascript 多级checkbox选择效果
2009/08/20 Javascript
javascript 动态设置已知select的option的value值的代码
2009/12/16 Javascript
javascript日期转换 时间戳转日期格式
2011/11/05 Javascript
Extjs单独定义各组件的实例代码
2013/06/25 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
VUEJS实战之修复错误并且美化时间(2)
2016/06/13 Javascript
JS中的hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()
2016/08/11 Javascript
JavaScript使用键盘输入控制实现数字验证功能
2016/08/19 Javascript
纯js实现悬浮按钮组件
2016/12/17 Javascript
关于jquery form表单序列化的注意事项详解
2017/08/01 jQuery
微信小程序之GET请求的实例详解
2017/09/29 Javascript
jquery的 filter()方法使用教程
2018/03/22 jQuery
angular4自定义表单控件[(ngModel)]的实现
2018/11/23 Javascript
js实现简单掷骰子小游戏
2019/10/24 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
2020/03/10 Javascript
vue el-tree 默认展开第一个节点的实现代码
2020/05/15 Javascript
举例讲解Python的Tornado框架实现数据可视化的教程
2015/05/02 Python
python使用wmi模块获取windows下硬盘信息的方法
2015/05/15 Python
简单了解django索引的相关知识
2019/07/17 Python
python打印文件的前几行或最后几行教程
2020/02/13 Python
文员岗位职责
2013/11/09 职场文书
机械设计及其自动化求职推荐信
2014/02/17 职场文书
人力资源部门的主要职能
2014/02/22 职场文书
政协会议宣传标语
2014/10/09 职场文书
单位收入证明范本
2015/06/18 职场文书
Python基础知识学习之类的继承
2021/05/31 Python
postgresql使用filter进行多维度聚合的解决方法
2021/07/16 PostgreSQL