在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高级程序设计 读书笔记之九 本地对象Array
Feb 27 Javascript
jquery删除数据记录时的弹出提示效果
May 06 Javascript
jquery插件jquery.dragscale.js实现拖拽改变元素大小的方法(附demo源码下载)
Feb 25 Javascript
jQuery实现的可编辑表格完整实例
Jun 20 Javascript
Angularjs 依赖压缩及自定义过滤器写法
Feb 04 Javascript
jquery滚动条插件slimScroll使用方法
Feb 09 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
Nov 27 Javascript
详解关于Vuex的action传入多个参数的问题
Feb 22 Javascript
Vue 组件修改根实例的数据的方法
Apr 02 Javascript
Vue源码解析之数据响应系统的使用
Apr 24 Javascript
node.js express框架简介与实现
Jul 23 Javascript
微信小程序纯文本实现@功能
Apr 08 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之第九天
2006/10/09 PHP
不错的PHP学习之php4与php5之间会穿梭一点点感悟
2007/05/03 PHP
ThinkPHP应用模式扩展详解
2014/07/16 PHP
php中使用in_array() foreach array_search() 查找数组是否包含时的性能对比
2015/04/14 PHP
PHP7标量类型declare用法实例分析
2016/09/26 PHP
告诉大家什么是JSON
2008/06/10 Javascript
JavaScript 高级语法介绍
2009/06/15 Javascript
jQuery jcrop插件截图使用方法
2013/11/20 Javascript
JavaScript对IE操作的经典代码(推荐)
2014/03/10 Javascript
基于javascript制作经典传统的拼图游戏
2016/03/22 Javascript
详解JavaScript设计模式开发中的桥接模式使用
2016/05/18 Javascript
javascript实现图片左右滚动效果【可自动滚动,有左右按钮】
2016/09/19 Javascript
基于Vuejs和Element的注册插件的编写方法
2017/07/03 Javascript
解决vue+element 键盘回车事件导致页面刷新的问题
2018/08/25 Javascript
Vue-input框checkbox强制刷新问题
2019/04/18 Javascript
微信小程序扫描二维码获取信息实例详解
2019/05/07 Javascript
layui使用label标签的方法
2019/09/14 Javascript
Javascript实现html转pdf高清版(提高分辨率)
2020/02/19 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
2020/04/14 Javascript
Python实现豆瓣图片下载的方法
2015/05/25 Python
恢复百度云盘本地误删的文件脚本(简单方法)
2017/10/21 Python
python获取当前目录路径和上级路径的实例
2018/04/26 Python
Python with关键字,上下文管理器,@contextmanager文件操作示例
2019/10/17 Python
Python 装饰器原理、定义与用法详解
2019/12/07 Python
python实现ssh及sftp功能(实例代码)
2020/03/16 Python
Python 连接 MySQL 的几种方法
2020/09/09 Python
python脚本定时发送邮件
2020/12/22 Python
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
.NET常见笔试题集
2012/12/01 面试题
党员培训思想汇报
2014/01/07 职场文书
美丽家庭事迹材料
2014/05/03 职场文书
2015年师德表现自我评价
2015/03/05 职场文书
雷锋的观后感
2015/06/10 职场文书
地心历险记观后感
2015/06/15 职场文书
浅谈怎么给Python添加类型标注
2021/06/08 Python