注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

和申的个人主页

专注于java开发,1985wanggang

 
 
 

日志

 
 

从谷歌的一个Bug说起,谈谈键盘事件的兼容性  

2009-02-13 10:58:17|  分类: Html/Js |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

从谷歌的一个Bug说起,谈谈键盘事件的兼容性 - 和申 - 和申的个人主页 从谷歌的一个Bug说起,谈谈键盘事件的兼容性 - 和申 - 和申的个人主页

上面是谷歌首页,当输入某个词时,下面会弹出自动补全提示。功能并不复杂,但考虑到要兼容各个浏览器,谷歌为此可能花费了不少功夫。然而完美实在是很难得,谷歌首页上一直有一个处理得不妥的Bug:

除了Ctrl+X/C/V,Ctrl+Z/Y也是经常使用的快捷键。在Firefox/Safari/Opera中访问谷歌,一切都很正常。但当我们打开IE浏览谷歌时,Ctrl+Z/Y不起作用了。在当今特别是中国,IE是份量最重的浏览器,谷歌首页有此问题,完全可以归为一个Bug.

这个Bug究竟是怎么引起的呢?为了进一步讨论,我们先来看看各个浏览器下,当输入法开启和未开启时,对键盘等事件的响应情况。

猛击查看 JavaScript键盘事件测试小结

通过上面这篇测试小结,我们可以看出,要实现谷歌的自动补全功能并不是一件很简单的事。目前可以找到的解决方案有:

方案一:通过监听keydown, keypress, keyup事件来实现。这是大部分JavaScript教科书里的做法,对于拉丁语系国家,是没有问题的。但输入法一开启后,一切就都不美妙了:

  1. 无论有没有输入法,通过鼠标右键粘贴复制时,key事件都触发不了,真糟糕。
  2. 输入法开启时,各个浏览器表现不同。不同输入法之间还有差异,太让人沮丧了。
  3. 输入法开启时,Opera压根不触发键盘事件。亲爱的Opera,叫我怎么爱上你?

考虑到中文用户,特别是第一条(不少中文用户习惯使用右键菜单来粘贴复制),第一个方案基本可以枪毙掉。

方案二:不考虑这些烦人的键盘事件,直接采用定时器来实现。在输入框获取焦点时,触发定时器,失去焦点时,关闭定时器。定时器每隔200ms检查输入框的值,根据值的变化来进行下一步响应。这个trick很简单,基本上能解决大部分问题(谷歌的自动完成就是这么做的^o^)。但有以下不妥:

  1. 性能问题。(因为仅在获取焦点时触发定时器,性能问题倒是可以不考虑的)
  2. ie下,此方法会导致Ctrl+Z/Y快捷键失效。
  3. firefox下,用定时器实现表单输入时的即时校验,当输入法开启时,如果校验函数在输入未完成时改变输入框的值,会导致输入框的值变成空。(这个属于不可忽视的Bug,很恼人)

方案二自动解决了右键菜单粘贴的问题,对于自动补全功能来说,一般应用场景下也足够用,但对谷歌来说,感觉有此Bug是不妥的。如果用方案二来实现表单输入时的即时校验,上面的第3点会导致firefox的中文用户很不爽。

苦思冥想许久,在键盘事件中折腾来折腾去,感觉怎么做都无法同时解决上面的所有不妥。昨天静下心来对所有A级浏览器的键盘事件在输入法开启和未开启时做了个仔细的测试后,下面这个方案就很清晰的浮了出来:

方案三:在上面的浏览器事件测试中,有一个很让人高兴的发现:所有浏览器中,都会触发input(ie下可以用propertychange)事件。而且input事件仅在输入框的值有变化时才会触发。在输入法开启时,input也能正常触发(虽然会触发一些冗余的input,但比起定时器来好很多)。在右键菜单粘贴等操作时,也能正确触发input. 采用input/propertychange, 几近完美。但需要注意以下几点:

  1. ie下,如果监听的事件函数中,有页面输出操作,如YAHOO.log(…), 会导致Ctrl+Z/Y失效。(深层次原因还需仔细探索,感觉页面输出操作只是表象)
  2. 对于表单输入时的即时校验来说,比如只能输入数字的输入框,当输入字母时,监听input事件的实现会在字母显示出来后,立刻又删除掉(和 keyup的实现效果一样),没有监听keypress的效果好(不会先显示出来)。因此对于即时校验来说,可以结合input和keypress,在输入法未开启时,给用户更友好的体验。

最后,看一个根据方案三来实现的简单例子:表单输入时的即时校验

参考资料

  评论这张
 
阅读(980)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016