在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 相关文章推荐
通用JS事件写法实现代码
Jan 07 Javascript
jquery 多级下拉菜单核心代码
May 21 Javascript
网页实时显示服务器时间和javscript自运行时钟
Jun 09 Javascript
jQuery中trigger()与bind()用法分析
Dec 18 Javascript
实例讲解JavaScript中instanceof运算符的用法
Jun 08 Javascript
jQuery Ajax全解析
Feb 13 Javascript
vue2.0 中#$emit,$on的使用详解
Jun 07 Javascript
Ionic项目中Native Camera的使用方法
Jun 07 Javascript
在 Angular中 使用 Lodash 的方法
Feb 11 Javascript
浅谈Angular 的变化检测的方法
Mar 01 Javascript
详解vue页面首次加载缓慢原因及解决方案
Nov 06 Javascript
关于Javascript闭包与应用的详解
Apr 22 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实现像JSP,ASP里Application那样的全局变量
2007/01/12 PHP
php 中文字符入库或显示乱码问题的解决方法
2010/04/12 PHP
php中debug_backtrace、debug_print_backtrace和匿名函数用法实例
2014/12/01 PHP
PHP const定义常量及global定义全局常量实例解析
2020/05/28 PHP
javascript 硬盘序列号+其它硬件信息
2008/12/23 Javascript
js post方式传递提交的实现代码
2010/05/31 Javascript
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
2010/06/18 Javascript
javascript向flash swf文件传递参数值注意细节
2012/12/11 Javascript
Javascript中数组sort和reverse用法分析
2014/12/30 Javascript
JavaScript数据类型检测代码分享
2015/01/26 Javascript
浅谈javascript中for in 和 for each in的区别
2015/04/23 Javascript
jquery小火箭返回顶部代码分享
2015/08/19 Javascript
js实现鼠标点击左上角滑动菜单效果代码
2015/09/06 Javascript
jQuery过滤特殊字符及JS字符串转为数字
2016/05/26 Javascript
JS中跨页面调用变量和函数的方法(例如a.js 和 b.js中互相调用)
2016/11/01 Javascript
vue.js中实现登录控制的方法示例
2018/04/23 Javascript
解决ie11 SCRIPT5011:不能执行已释放Script的代码问题
2019/05/05 Javascript
layer弹出层自定义提交取消按钮的例子
2019/09/10 Javascript
Nuxt v-bind绑定img src不显示的解决
2019/12/05 Javascript
JavaScript TAB栏切换效果的示例
2020/11/05 Javascript
[43:32]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS NewBee第一场
2014/05/26 DOTA
python使用xlrd实现检索excel中某列含有指定字符串记录的方法
2015/05/09 Python
Python基于Matplotlib库简单绘制折线图的方法示例
2017/08/14 Python
Python实现自定义顺序、排列写入数据到Excel的方法
2018/04/23 Python
python 读取竖线分隔符的文本方法
2018/12/20 Python
Python 数据可视化pyecharts的使用详解
2019/06/26 Python
Python configparser模块操作代码实例
2020/06/08 Python
使用sublime text3搭建Python编辑环境的实现
2021/01/12 Python
alice McCALL官网:澳大利亚时尚品牌
2020/11/16 全球购物
暑期研修感言
2014/02/17 职场文书
学习演讲稿范文
2014/05/10 职场文书
2016年12月份红领巾广播稿
2015/12/21 职场文书
承诺书应该怎么写?
2019/09/10 职场文书
MySQL优化之如何写出高质量sql语句
2021/05/17 MySQL
Python实现滑雪小游戏
2021/09/25 Python
Java实现简单小画板
2022/06/10 Java/Android