在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 相关文章推荐
二行代码解决全部网页木马
Mar 28 Javascript
一个轻量级的javascript库 pj介绍
Dec 19 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
Jan 10 Javascript
JavaScript异步编程Promise模式的6个特性
Apr 03 Javascript
javascritp添加url参数将参数加入到url中
Sep 25 Javascript
jquery中ajax使用error调试错误的方法
Feb 08 Javascript
解决JS无法调用Controller问题的方法
Dec 31 Javascript
jQuery Ajax实现跨域请求
Jan 21 Javascript
JS使用数组实现的队列功能示例
Mar 04 Javascript
vscode vue 文件模板的配置方法
Jul 23 Javascript
layer.alert回调函数执行关闭弹窗的实例
Sep 11 Javascript
Vue数据双向绑定原理实例解析
May 15 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结合ACCESS的跨库查询功能
2015/06/12 PHP
php检测文本的编码
2015/07/26 PHP
对YUI扩展的Gird组件 Part-2
2007/03/10 Javascript
jquery中eq和get的区别与使用方法
2011/04/14 Javascript
Jquery实现搜索框提示功能示例代码
2013/08/13 Javascript
js 判断控件获得焦点的示例代码
2014/03/04 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
2015/09/01 Javascript
Javascript闭包实例详解
2015/11/29 Javascript
js格式化时间的方法
2015/12/18 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
2015/12/24 Javascript
Bootstrap页面布局基础知识全面解析
2016/06/13 Javascript
微信小程序 跳转方式总结
2017/04/20 Javascript
利用JS代码自动删除稿件的普通弹幕功能
2019/09/20 Javascript
解决node终端下运行js文件不支持ES6语法
2020/04/04 Javascript
javascript 易错知识点实例小结
2020/04/25 Javascript
React.js组件实现拖拽排序组件功能过程解析
2020/04/27 Javascript
Angular短信模板校验代码
2020/09/23 Javascript
在Mac OS上搭建Python的开发环境
2015/12/24 Python
Python连接PostgreSQL数据库的方法
2016/11/28 Python
matplotlib在python上绘制3D散点图实例详解
2017/12/09 Python
关于 Python opencv 使用中的 ValueError: too many values to unpack
2019/06/28 Python
python函数enumerate,operator和Counter使用技巧实例小结
2020/02/22 Python
python实现凯撒密码、凯撒加解密算法
2020/06/11 Python
遇到的Mysql的面试题
2014/06/29 面试题
超市5.1促销活动
2014/01/15 职场文书
争论的故事教学反思
2014/02/06 职场文书
根叔历年演讲稿
2014/05/20 职场文书
节电标语大全
2014/06/23 职场文书
2014大学生批评与自我批评思想汇报
2014/09/21 职场文书
财务部岗位职责
2015/02/03 职场文书
上学路上观后感
2015/06/16 职场文书
婚礼家长致辞
2015/07/27 职场文书
python实现批量提取指定文件夹下同类型文件
2021/04/05 Python
Redis IP地址的绑定的实现
2021/05/08 Redis
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/07 其他游戏
Java数组详细介绍及相关工具类
2022/04/14 Java/Android