在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 相关文章推荐
两种WEB下的模态对话框 (asp.net或js的分别实现)
Dec 02 Javascript
小议Javascript中的this指针
Mar 18 Javascript
基于JQuery的Pager分页器实现代码
Jul 17 Javascript
JavaScript中的console.time()函数详细介绍
Dec 29 Javascript
JS实现图片高斯模糊切换效果的焦点图实例
Jan 21 Javascript
AngularJS中$http的交互问题
Mar 29 Javascript
详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)
Jul 13 Javascript
Makefile/cmake/node-gyp中区分判断不同平台的方法
Dec 18 Javascript
详解使用React.memo()来优化函数组件的性能
Mar 19 Javascript
vue-cli 3 全局过滤器的实例代码详解
Jun 03 Javascript
vue + typescript + video.js实现 流媒体播放 视频监控功能
Jul 07 Javascript
Vue+webpack实现懒加载过程解析
Feb 17 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
在Win2003(64位)中配置IIS6+PHP5.2.17+MySQL5.5的运行环境
2016/04/04 PHP
PHP的AES加密算法完整实例
2016/07/20 PHP
用jQuery中的ajax分页实现代码
2011/09/20 Javascript
为JavaScript类型增加方法的实现代码(增加功能)
2011/12/29 Javascript
js自动查找select下拉的菜单并选择(示例代码)
2014/02/26 Javascript
JavaScript函数详解
2015/02/27 Javascript
js实现网页多级级联菜单代码
2015/08/20 Javascript
JavaScript类的写法
2016/09/17 Javascript
使用原生的javascript来实现轮播图
2017/02/24 Javascript
JS正则表达式常见用法实例详解
2018/06/19 Javascript
vue中倒计时组件的实例代码
2018/07/06 Javascript
在vue中使用G2图表的示例代码
2019/03/19 Javascript
[49:21]完美世界DOTA2联赛循环赛 Ink Ice vs LBZS BO2第二场 11.05
2020/11/06 DOTA
Python中利用sorted()函数排序的简单教程
2015/04/27 Python
深入探究Python中变量的拷贝和作用域问题
2015/05/05 Python
python开发之函数定义实例分析
2015/11/12 Python
浅谈Tensorflow模型的保存与恢复加载
2018/04/26 Python
Ubuntu下使用python读取doc和docx文档的内容方法
2018/05/08 Python
Python 中字符串拼接的多种方法
2018/07/30 Python
Django框架使用富文本编辑器Uedit的方法分析
2018/07/31 Python
python 一个figure上显示多个图像的实例
2019/07/08 Python
python找出因数与质因数的方法
2019/07/25 Python
python代码 FTP备份交换机配置脚本实例解析
2019/08/01 Python
TensorFlow索引与切片的实现方法
2019/11/20 Python
使用pytorch完成kaggle猫狗图像识别方式
2020/01/10 Python
关于css兼容性问题及一些常见问题汇总
2016/05/03 HTML / CSS
春秋航空官方网站:Spring Airlines
2017/09/27 全球购物
大班幼儿评语大全
2014/04/30 职场文书
暑期学习心得体会
2014/09/02 职场文书
简易离婚协议书(范本)
2014/10/25 职场文书
2014年终个人工作总结
2014/11/07 职场文书
2015年房地产销售工作总结
2015/04/20 职场文书
nginx简单配置多个server的方法
2021/03/31 Servers
Go语言空白表示符_的实例用法
2021/07/04 Golang
利用JavaScript写一个简单计算器
2021/11/27 Javascript
苹果电脑mac os中货币符号快捷输入
2022/02/17 杂记