在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 相关文章推荐
在b/s开发中经常用到的javaScript技术
Aug 23 Javascript
页面版文本框智能提示JS代码
Nov 20 Javascript
jquery更换文章内容与改变字体大小代码
Sep 30 Javascript
禁用Tab键JS代码兼容Firefox和IE
Apr 18 Javascript
Egret引擎开发指南之视觉编程
Sep 03 Javascript
jquery实现submit提交表单
Feb 03 Javascript
基于BootStrap Metronic开发框架经验小结【一】框架总览及菜单模块的处理
May 12 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
Dec 19 Javascript
Vuex的actions属性的具体使用
Apr 14 Javascript
微信小程序页面上下滚动效果
Nov 18 Javascript
vue递归组件实战之简单树形控件实例代码
Aug 27 Javascript
element-ui中按需引入的实现
Dec 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建立Ftp连接的方法
2015/03/07 PHP
curl和libcurl的区别简介
2015/07/01 PHP
PHP-FPM 的管理和配置详解
2019/02/17 PHP
js 剪切板的用法(clipboardData.setData)与js match函数介绍
2013/11/19 Javascript
js二维数组排序的简单示例代码
2014/01/24 Javascript
JavaScript实现查找字符串中第一个不重复的字符
2014/12/29 Javascript
js实现跟随鼠标移动且带关闭功能的图片广告实例
2015/02/26 Javascript
JS实现向表格行添加新单元格的方法
2015/03/30 Javascript
JS 实现Base64编码与解码实例详解
2016/11/07 Javascript
VsCode插件整理(小结)
2017/09/14 Javascript
禁止弹窗中蒙层底部页面跟随滚动的几种方法
2017/12/07 Javascript
javascript实现对话框功能警告(alert 消息对话框)确认(confirm 消息对话框)
2019/05/07 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
2019/11/01 Javascript
Vue中多元素过渡特效的解决方案
2020/02/05 Javascript
基于vue3.0.1beta搭建仿京东的电商H5项目
2020/05/06 Javascript
JS实现canvas简单小画板功能
2020/06/23 Javascript
Vue.js中Line第三方登录api的实现代码
2020/06/29 Javascript
python处理文本文件实现生成指定格式文件的方法
2014/07/31 Python
python django 访问静态文件出现404或500错误
2017/01/20 Python
python print出共轭复数的方法详解
2019/06/25 Python
DJango的创建和使用详解(默认数据库sqlite3)
2019/11/18 Python
python元组的概念知识点
2019/11/19 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
Django操作session 的方法
2020/03/09 Python
浅析关于Keras的安装(pycharm)和初步理解
2020/10/23 Python
pip 20.3 新版本发布!即将抛弃 Python 2.x(推荐)
2020/12/16 Python
python压包的概念及实例详解
2021/02/17 Python
北美三大旅游网站之一:Travelocity加拿大
2016/08/20 全球购物
Blue Nile中国官网:全球知名的钻石和珠宝网络零售商
2020/03/22 全球购物
专科毕业生自我鉴定
2013/12/01 职场文书
优秀高中生事迹材料
2014/02/11 职场文书
厨师个人自我鉴定范文
2014/04/19 职场文书
给市场的环保建议书
2014/05/14 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
vue如何使用模拟的json数据查看效果
2022/03/31 Vue.js
Windows server 2003卸载和安装IIS的图文教程
2022/07/15 Servers