在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 相关文章推荐
jquery tab插件制作实现代码
Jun 22 Javascript
JS鼠标滑过图片时切换图片实现思路
Sep 12 Javascript
js 异步操作回调函数如何控制执行顺序
Dec 24 Javascript
改变隐藏的input中value值的方法
Mar 19 Javascript
js生成验证码并直接在前端判断
May 15 Javascript
详解JavaScript对Date对象的操作问题(生成一个倒数7天的数组)
Oct 01 Javascript
jQuery鼠标悬浮链接弹出跟随图片实例代码
Jan 08 Javascript
Vue.js每天必学之表单控件绑定
Sep 05 Javascript
不使用script导入js文件的几种方法
Oct 27 Javascript
jQuery实现倒计时(倒计时年月日可自己输入)
Dec 02 Javascript
Vue CLI3 如何支持less的方法示例
Aug 29 Javascript
layui实现图片虚拟路径上传,预览和删除的例子
Sep 25 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 学习资料零碎东西
2010/12/04 PHP
用 Composer构建自己的 PHP 框架之基础准备
2014/10/30 PHP
php中chdir()函数用法实例
2014/11/13 PHP
解读PHP中上传文件的处理问题
2016/05/29 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
2020/02/21 PHP
可以用来调试JavaScript错误的解决方案
2010/08/07 Javascript
javascipt匹配单行和多行注释的正则表达式
2013/11/20 Javascript
js实现的GridView即表头固定表体有滚动条且可滚动
2014/02/19 Javascript
CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法
2015/05/12 Javascript
JQuery球队选择实例
2015/05/18 Javascript
js跨浏览器的事件侦听器和事件对象的使用方法
2015/12/17 Javascript
jQuery Easyui使用(二)之可折叠面板动态加载无效果的解决方法
2016/08/17 Javascript
JavaScript实现拖拽元素对齐到网格(每次移动固定距离)
2016/11/30 Javascript
jQuery.Validate表单验证插件的使用示例详解
2017/01/04 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
jQuery EasyUI ProgressBar进度条组件
2017/02/28 Javascript
Javascript中字符串相关常用的使用方法总结
2017/03/13 Javascript
ztree简介_动力节点Java学院整理
2017/07/19 Javascript
vue-better-scroll 的使用实例代码详解
2018/12/03 Javascript
深入理解js A*寻路算法原理与具体实现过程
2018/12/13 Javascript
python列表与元组详解实例
2013/11/01 Python
Python操作sqlite3快速、安全插入数据(防注入)的实例
2014/04/26 Python
Python爬虫天气预报实例详解(小白入门)
2018/01/24 Python
使用pandas read_table读取csv文件的方法
2018/07/04 Python
使用python批量修改文件名的方法(视频合并时)
2020/03/24 Python
对python中assert、isinstance的用法详解
2019/11/27 Python
python实现程序重启和系统重启方式
2020/04/16 Python
keras 读取多标签图像数据方式
2020/06/12 Python
西班牙太阳镜品牌:Hawkers
2018/03/11 全球购物
Nisbets法国:英国最大的厨房和餐饮设备供应商
2019/03/18 全球购物
研修第一天随笔感言
2014/02/15 职场文书
寒假社会实践个人总结
2015/03/06 职场文书
2015年护士工作总结范文
2015/03/31 职场文书
2015年护理工作总结范文
2015/04/03 职场文书
上班旷工检讨书
2015/08/15 职场文书
导游词之无锡唐城
2019/12/12 职场文书