在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的9个陷阱及评点分析
May 16 Javascript
基于jquery跨浏览器显示的file上传控件
Oct 24 Javascript
jquery地址栏链接与a标签链接匹配之特效代码总结
Aug 24 Javascript
JavaScript操作HTML元素和样式的方法详解
Oct 21 Javascript
JS中多步骤多分步的StepJump组件实例详解
Apr 01 Javascript
JavaScript toUpperCase()方法使用详解
Aug 26 Javascript
AngularJS使用ng-Cloak阻止初始化闪烁问题的方法
Nov 03 Javascript
javascript基础练习之翻转字符串与回文
Feb 20 Javascript
javascript填充默认头像方法
Feb 22 Javascript
vue中引入mxGraph的步骤详解
May 17 Javascript
laypage.js分页插件使用方法详解
Jul 27 Javascript
vue中选中多个选项并且改变选中的样式的实例代码
Sep 16 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
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
php实现encode64编码类实例
2015/03/24 PHP
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解
2020/06/05 PHP
QQ登录简单实现代码
2021/03/09 Javascript
用js实现下载远程文件并保存在本地的脚本
2008/05/06 Javascript
jQuery 技巧大全(新手入门篇)
2009/05/12 Javascript
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
Js动态添加复选框Checkbox的实例方法
2013/04/08 Javascript
js实现图片旋转的三种方法
2014/04/10 Javascript
Javascript基础教程之while语句
2015/01/18 Javascript
NodeJS学习笔记之Connect中间件模块(一)
2015/01/27 NodeJs
TinyMCE提交AjaxForm获取不到数据的解决方法
2015/03/05 Javascript
js实现简洁的TAB滑动门效果代码
2015/09/06 Javascript
学习Javascript闭包(Closure)知识
2016/08/07 Javascript
vue分页组件table-pagebar使用实例解析
2020/11/15 Javascript
Vue自定义指令介绍(2)
2016/12/08 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
详解如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
2017/06/01 jQuery
JavaScript实现二叉树的先序、中序及后序遍历方法详解
2017/10/26 Javascript
js删除数组中的元素delete和splice的区别详解
2018/02/03 Javascript
vue下拉菜单组件(含搜索)的实现代码
2018/11/25 Javascript
es6中reduce的基本使用方法
2019/09/10 Javascript
Javascript文本框脚本实现方法解析
2020/10/30 Javascript
[06:07]刀塔密之二:攻之吾命受之吾幸
2014/07/03 DOTA
python调用百度语音REST API
2018/08/30 Python
浅谈Django+Gunicorn+Nginx部署之路
2019/09/11 Python
Python批量将图片灰度化的实现代码
2020/04/11 Python
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
新加坡最佳婴儿用品店:Mamahood.com.sg
2018/08/26 全球购物
int和Integer有什么区别
2013/05/25 面试题
网页设计个人找工作求职信
2013/11/28 职场文书
学生手册家长评语
2014/02/10 职场文书
python批量更改目录名/文件名的方法
2021/04/18 Python
为Centos安装指定版本的Docker
2022/04/01 Servers
Android实现图片九宫格
2022/06/28 Java/Android
CSS 实现磨砂玻璃(毛玻璃)效果样式
2023/05/21 HTML / CSS