在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 相关文章推荐
50款非常棒的 jQuery 插件分享
Mar 29 Javascript
js判断上传文件的类型和大小示例代码
Oct 18 Javascript
基于jquery自定义的漂亮单选按钮RadioButton
Nov 19 Javascript
JS动态添加与删除select中的Option对象(示例代码)
Dec 20 Javascript
jQuery封装的tab选项卡插件分享
Jun 16 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
Dec 26 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
Aug 02 Javascript
javascript for循环性能测试示例
Aug 07 Javascript
Vue实现页面添加水印功能
Nov 09 Javascript
TypeScript高级用法的知识点汇总
Dec 17 Javascript
Vuex模块化应用实践示例
Feb 03 Javascript
原生JavaScript实现贪吃蛇游戏
Nov 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
星际实力自我测试
2020/03/04 星际争霸
php md5下16位和32位的实现代码
2008/04/09 PHP
php正则替换处理HTML页面的方法
2015/06/17 PHP
php实现保存周期为1天的购物车类
2017/07/07 PHP
jquery之empty()与remove()区别说明
2010/09/10 Javascript
JS中getYear()和getFullYear()区别分析
2014/07/04 Javascript
JavaScript的null和undefined区别示例介绍
2014/09/15 Javascript
javascript 面向对象封装与继承
2014/11/27 Javascript
js获取时间并实现字符串和时间戳之间的转换
2015/01/05 Javascript
JavaScript实现鼠标滑过图片变换效果的方法
2015/04/16 Javascript
js过滤HTML标签完整实例
2015/11/26 Javascript
全面解析Bootstrap手风琴效果
2020/04/17 Javascript
jQuery实现的导航动画效果(附demo源码)
2016/04/01 Javascript
文本溢出插件jquery.dotdotdot.js使用方法详解
2017/06/22 jQuery
微信小程序之前台循环数据绑定
2017/08/18 Javascript
vue脚手架中配置Sass的方法
2018/01/04 Javascript
vue中axios的封装问题(简易版拦截,get,post)
2018/06/15 Javascript
jQuery实现基本隐藏与显示效果的方法详解
2018/09/05 jQuery
JQuery判断radio单选框是否选中并获取值的方法
2019/01/17 jQuery
[20:39]DOTA2-DPC中国联赛 正赛开幕式 1月18日
2021/03/11 DOTA
Python中endswith()函数的基本使用
2015/04/07 Python
Python类的定义、继承及类对象使用方法简明教程
2015/05/08 Python
在python中bool函数的取值方法
2018/11/01 Python
在pandas多重索引multiIndex中选定指定索引的行方法
2018/11/16 Python
Python读取excel指定列生成指定sql脚本的方法
2018/11/28 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
python新式类和经典类的区别实例分析
2020/03/23 Python
python Timer 类使用介绍
2020/12/28 Python
世界上最全面的草药补充剂和顶级品牌维生素网站:HerbsPro
2019/01/20 全球购物
公司同意接收函
2014/01/13 职场文书
七年级地理教学反思
2014/01/26 职场文书
《我的第一本书》教学反思
2014/02/15 职场文书
高中军训感言200字
2014/02/23 职场文书
学校节能宣传周活动总结
2014/07/09 职场文书
经营目标管理责任书
2014/07/25 职场文书
病假证明模板
2015/06/19 职场文书