在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 相关文章推荐
JavaScript自定义日期格式化函数详细解析
Jan 14 Javascript
JavaScript中使用自然对数ln的方法
Jun 14 Javascript
jQuery实现的简单折叠菜单(折叠面板)效果代码
Sep 16 Javascript
javascript代码调试之console.log 用法图文详解
Sep 30 Javascript
微信小程序 倒计时组件实现代码
Oct 24 Javascript
JS验证input输入框(字母,数字,符号,中文)
Mar 23 Javascript
Angularjs 1.3 中的$parse实例代码
Sep 14 Javascript
vue webuploader 文件上传组件开发
Sep 23 Javascript
利用ES6实现单例模式及其应用详解
Dec 09 Javascript
jQuery实现的简单获取索引功能示例
Jun 04 jQuery
javascript绘制简单钟表效果
Apr 07 Javascript
JS Object构造函数之Object.freeze
Apr 28 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 存储文本换行实现方法
2010/01/05 PHP
PHP关联链接常用代码
2012/11/05 PHP
PHP内核探索:变量概述
2014/01/30 PHP
PHP防范SQL注入的具体方法详解(测试通过)
2014/05/09 PHP
ThinkPHP CURD方法之where方法详解
2014/06/18 PHP
Yii入门教程之Yii安装及hello world
2014/11/25 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
BOOM vs RR BO3 第二场2.13
2021/03/10 DOTA
JavaScript 异步调用框架 (Part 2 - 用例设计)
2009/08/03 Javascript
基于Unit PNG Fix.js有时候在ie6下不正常的解决办法
2013/06/26 Javascript
Javascript中call的两种用法实例
2013/12/13 Javascript
jquery和css3实现的炫酷时尚的菜单导航
2014/09/01 Javascript
创建js对象和js类的方法汇总
2014/12/24 Javascript
过期软件破解办法实例详解
2017/01/04 Javascript
基于Node的React图片上传组件实现实例代码
2017/05/10 Javascript
AngularJS  ng-repeat遍历输出的用法
2017/06/19 Javascript
angular指令笔记ng-options的使用方法
2017/09/18 Javascript
vue router+vuex实现首页登录验证判断逻辑
2018/05/17 Javascript
vue-cli 构建骨架屏的方法示例
2018/11/08 Javascript
vue 框架下自定义滚动条(easyscroll)实现方法
2019/08/29 Javascript
JS+CSS实现随机点名(实例代码)
2019/11/04 Javascript
python定时采集摄像头图像上传ftp服务器功能实现
2013/12/23 Python
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
2014/07/18 Python
Python实现的生产者、消费者问题完整实例
2018/05/30 Python
ubuntu上安装python的实例方法
2019/09/30 Python
Django rest framework分页接口实现原理解析
2020/08/21 Python
AVON雅芳官网:世界上最大的美容化妆品公司之一
2016/11/02 全球购物
Stefania Mode美国:奢华设计师和时尚服装
2018/01/07 全球购物
保护动物的标语
2014/06/11 职场文书
多媒体编辑专业毕业生求职信
2014/06/13 职场文书
生产助理岗位职责
2014/06/18 职场文书
2014年乡镇卫生院工作总结
2014/11/24 职场文书
会计求职自荐信范文
2015/03/04 职场文书
2019年第四季度财务部门工作计划
2019/11/02 职场文书
MySQL基于索引的压力测试的实现
2021/11/07 MySQL
frg-100简单操作(设置)说明
2022/04/05 无线电