在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 相关文章推荐
phpwind放自动注册方法
Dec 02 Javascript
web前端开发也需要日志
Dec 09 Javascript
表单提交前触发函数返回true表单才会提交
Mar 11 Javascript
javascript删除一个html元素节点的方法
Dec 20 Javascript
JS常用字符串方法(推荐)
Jan 15 Javascript
jquery ajax后台返回list,前台用jquery遍历list的实现
Oct 30 Javascript
JS中SetTimeout和SetInterval使用初探
Mar 23 Javascript
详解Vue CLI3配置之filenameHashing使用和源码设计使用和源码设计
Aug 31 Javascript
Vuex 快速入门(简单易懂)
Sep 20 Javascript
JavaScript事件对象深入详解
Dec 30 Javascript
js获取form表单中name属性的值
Feb 27 Javascript
前端vue-cli项目中使用img图片和background背景图的几种方法
Nov 13 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代码包装修正版
2008/03/15 PHP
基于empty函数的输出详解
2013/06/17 PHP
php数组删除元素示例
2014/03/21 PHP
php操作XML、读取数据和写入数据的实现代码
2014/08/15 PHP
PHP实现阳历到农历转换的类实例
2015/03/07 PHP
php+MySQL实现登录时验证登录名和密码是否正确
2016/05/10 PHP
addRule在firefox下的兼容写法
2006/11/30 Javascript
JavaScript获得选中文本内容的方法
2008/12/02 Javascript
Javascript document.referrer判断访客来源网址
2020/05/15 Javascript
Jquery Ajax学习实例3 向WebService发出请求,调用方法返回数据
2010/03/16 Javascript
将光标定位于输入框最右侧实现代码
2012/12/04 Javascript
jQuery 实现自动填充邮箱功能(带下拉提示)
2014/10/14 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
2016/06/07 Javascript
详解webpack es6 to es5支持配置
2017/05/04 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
2017/05/07 Javascript
JS面试题大坑之隐式类型转换实例代码
2018/10/14 Javascript
js 动态校验开始结束时间的实现代码
2020/05/25 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
Vue通过provide inject实现组件通信
2020/09/03 Javascript
Python中函数eval和ast.literal_eval的区别详解
2017/08/10 Python
Python日志模块logging基本用法分析
2018/08/23 Python
python 随机打乱 图片和对应的标签方法
2018/12/14 Python
python中for循环把字符串或者字典添加到列表的方法
2019/07/20 Python
Python单元测试工具doctest和unittest使用解析
2019/09/02 Python
Window10下python3.7 安装与卸载教程图解
2019/09/30 Python
浅谈python的elementtree模块处理中文注意事项
2020/03/06 Python
使用Html5、CSS实现文字阴影效果
2018/01/17 HTML / CSS
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
德国知名健康零食网上商店:Seeberger
2017/07/27 全球购物
找工作最新求职信
2013/12/22 职场文书
小学母亲节活动总结
2015/02/10 职场文书
2016年春季运动会加油稿
2015/07/22 职场文书
辞职信怎么写?
2019/05/21 职场文书
Go语言实现Snowflake雪花算法
2021/06/08 Golang
一文了解MySQL二级索引的查询过程
2022/02/24 MySQL
如何在Python中妥善使用进度条详解
2022/04/05 Python