在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 相关文章推荐
Javascript 同时提交多个Web表单的方法
Feb 19 Javascript
理解Javascript_14_函数形式参数与arguments
Oct 20 Javascript
JavaScript获得页面base标签中url的方法
Apr 03 Javascript
简述AngularJS相关的一些编程思想
Jun 23 Javascript
angular.js分页代码的实例
Jul 27 Javascript
js插件Jcrop自定义截取图片功能
Oct 14 Javascript
zTree获取当前节点的下一级子节点数实例
Sep 05 Javascript
仿京东快报向上滚动的实例
Dec 13 Javascript
javascript中的event loop事件循环详解
Dec 14 Javascript
Angular PWA使用的Demo示例
Jan 31 Javascript
vue实现自定义多选按钮
Jul 16 Javascript
详解如何解决使用JSON.stringify时遇到的循环引用问题
Mar 23 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 include任意文件或URL介绍
2014/04/29 PHP
php生成酷炫的四个字符验证码
2016/04/22 PHP
PHP+mysql+ajax轻量级聊天室实现方法详解
2016/10/17 PHP
jQuery ui 1.7更新小结
2009/08/15 Javascript
JavaScript之自定义类型
2012/05/04 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
js防止页面被iframe调用的方法
2014/10/30 Javascript
jQuery实现仿淘宝带有指示条的图片转动切换效果完整实例
2015/03/04 Javascript
轻松实现js图片预览功能
2016/01/18 Javascript
JavaScript编写点击查看大图的页面半透明遮罩层效果实例
2016/05/09 Javascript
分享十三个最佳JavaScript数据网格库
2017/04/07 Javascript
运用jQuery写的验证表单(实例讲解)
2017/07/06 jQuery
关于vue.js发布后路径引用的问题解决
2017/08/15 Javascript
一个简易时钟效果js实现代码
2020/03/25 Javascript
JsChart组件使用详解
2018/03/04 Javascript
基于vue中对鼠标划过事件的处理方式详解
2018/08/22 Javascript
Jquery实现无缝向上循环滚动列表的特效
2019/02/13 jQuery
Vue项目中使用better-scroll实现菜单映射功能方法
2019/09/11 Javascript
如何利用Node.js与JSON搭建简单的动态服务器
2020/06/16 Javascript
Python的迭代器和生成器
2015/07/29 Python
python用Pygal如何生成漂亮的SVG图像详解
2017/02/10 Python
用python3教你任意Html主内容提取功能
2018/11/05 Python
django-rest-framework解析请求参数过程详解
2019/07/18 Python
Django解决frame拒绝问题的方法
2020/12/18 Python
深入浅析css3 中display box使用方法
2015/11/25 HTML / CSS
美国唇部护理专家:Sara Happ
2019/06/19 全球购物
简述数据库的设计过程
2015/06/22 面试题
村官工作鉴定评语
2014/01/27 职场文书
党的群众路线教育实践活动对照检查材料范文
2014/09/24 职场文书
教师四风自我剖析材料
2014/09/30 职场文书
2014年幼儿园保育工作总结
2014/12/02 职场文书
幼儿教师个人总结
2015/02/05 职场文书
小学秋季运动会加油口号及加油稿
2019/08/19 职场文书
Vue如何实现组件间通信
2021/05/15 Vue.js
图片批量处理 - 尺寸、格式、水印等
2022/03/07 杂记
golang操作rocketmq的示例代码
2022/04/06 Golang