realazy


输入法下keyup失效的解决方案

在某些情况下,比如自动补全(auto complete)的输入框中,需要使用keyup事件来监听键盘的输入以迅速作出回应。

关键在于keyup, 如果世界是美好的,那么就不会有这篇blog. 可是……

世界是不美好的。我们活在中文世界,我们要用输入法。在输入法开启的情况下,您会碰到不美好的事情:keyup失效。对于您绑定到keyup的任何回调函数,除非您把输入法切换回英文状态,否则它会无动于衷。如果能称之为bug,我会很高兴,因为bug会有修复的可能,如果是特征(feature),那么,我只好叹息一下。

问题

在开启输入法的情况下,三个浏览器的具体问题如下:

  • IE:触发keydown和keyup, 不触发keypress. 能够获得输入值。
  • Firefox:触发keydown和keypress, 不触发keyup. 输入值未能获得。在回车后会触发keyup, 可获得输入值。
  • Opera:keydown, keypress和keyup都不触发,输入值也未能获。

(如果您能帮我试用一下Safari,我会很高兴并谢谢您。这里有一个测试页面:http://tonextone.com/test/eventTest.html

解决方案

总结出以上问题,没有兴奋反而陷入绝望,因为没有google出解决方案(是的,对于拉丁语系的老外来说,不会存在输入法)。但是,wait, 谷歌搜索的自动补全不是工作得好好的吗?于是研究一下这个 http://www.google.cn/ac.js。嘿嘿,虽然混淆得还可以,但还是可以发现蛛丝马脚的。它使用一个计时器,当输入框处于聚焦(focus)状态时,每 10 毫秒执行一次回调函数。

虽然挺耗资源(所以建议在输入框失焦(blur)时,一定要清除这个计时器),但也只能如此了。作前端开发的,不仅要与语言(JavaScript, CSS, HTML) 斗,还要与浏览器斗,其乐无穷也。

更新:IE 有一个 onpropertychange 事件处理器可以随时检测变化,对应之,Firefox 和 Opera 有一个 oninput 事件处理器也可以达到目的。遗憾的是,在输入法开启的情况下,Opera对于 oninput 也没法随时监听(表现在:输入英文字母可以监听到,而中文则失效)。如果不考虑 Opera, IE使用 onpropertychange 而 Firefox 使用 oninput, 也可解决我们上述问题。

另外需要注意的是, oninput 比较诡异,您可以<input oninput="jsFunc()" ... />来绑定,也可以用addEventListener来绑定,就是不能使用 DOM 0 的element.oninput = function(){} 的形式来绑定,否则不生效。

未曾测试Safari, 有心者可自行测试之。

20 Responses to “输入法下keyup失效的解决方案”

  1. terababy Says:

    终于能够感觉到做网站和企业应用如何不同了。做企业应用只要做IE就可以了,因为可以要求用户统一用IE。所以虽然貌似这种问题过去遇到过也都轻轻飘过了。

  2. sixfooter Says:

    safari
    我试过了
    可以获得值.

  3. aoao Says:

    我猜这篇一定是跟微软拼音有关。=。=
    其实我以前也撞到过。。。。。。
    对了。我换域名了。下面改改地址。

  4. kakawar Says:

    感谢你的分享。

    我们最近做的一个网站,登陆框不知怎么回事,按回车键无法提交。所以我想写个函数,在输入框获得焦点的时候,用keypress模拟提交事件。

    请教一下,怎样判断一个输入框处于聚焦状态呢?我没有查到专门的属性。现在打算在输入框onfocus的时候绑定一个函数,onblur的时候取消它,这样做是不是太笨了呢……

  5. Cloudream Says:

    Safari出发down和up,但只有keyup正确找到输入内容

    keyDown:å(229) :
    keyPress:(0) :
    keyUp:A(65) :
    keyDown:å(229) :
    keyPress:(0) :
    keyUp:D(68) :
    keyDown:å(229) :
    keyPress:(0) :
    keyUp:F(70) :
    keyDown:å(229) :
    keyPress:(0) :
    keyUp:E(69) :

  6. Bonede Says:

    还是比较偏向使用计时器。
    用事件感觉有点怪。

  7. realazy Says:

    @aoao

    貌似只有一些不常用的输入法比如陈桥五笔(未测试)之类才没有问题。

    @kakawar

    只能是这么做。不过可以先把主要的函数写好,onfocus/onblur只是作为一个计时器开关而已。

    @Cloudream

    非常感谢。

    @Bonede

    从理论上说,应该是监听事件比较合适。但是既然有问题,那么只好用计时器了。这属于trick了。

  8. Gawain Says:

    我在safari下使用,OpenVanilla+自己的五笔码表,没有问题

    keyDown:K(75) :
    keyUp:K(75) : 口
    keyDown:W(87) : 口
    keyUp:W(87) : 口人
    keyDown:G(71) : 口人
    keyUp:G(71) : 口人王
    keyDown: (32) : 口人王
    keyUp: (32) : 哈
    keyDown:K(75) : 哈
    keyUp:K(75) : 哈口
    keyDown:W(87) : 哈口
    keyUp:W(87) : 哈口人
    keyDown:G(71) : 哈口人
    keyUp:G(71) : 哈口人王
    keyDown: (32) : 哈口人王
    keyUp: (32) : 哈哈
    onChange:哈哈

  9. aw Says:

    1、与浏览器斗
    2、与输入法斗
    3、与变态用户斗

  10. safe6 Says:

    感谢你的分享。
    学习了,支持一下。

  11. 哉崽 Says:

    最近也写了一个自动完成的JS,因为是针对英文查询绑定动作的,所以没碰到过输入法问题,看来等以后扩展中文输入的时候,问题就明显起来了,呵呵

    淘宝上不是也有一个类似的自动提示吗?不知道啥方法来绕过解决这个问题,有空去研究下,嘿嘿

  12. jjgod Says:

    Safari works fine.

  13. March Says:

    虽然和输入法没多少关系,但是对键盘事件的讲解很详细:
    http://unixpapa.com/js/key.html

  14. sea Says:

    FF2.0下使用测试:
    keyDown:(17) :
    keyUp: (32) :
    keyUp:(17) : keyDown:å(229) :
    keyPress:å(229) :
    keyUp: (32) : 你keyDown:å(229) : 你
    keyPress:å(229) : 你
    keyUp: (32) : 你好

    IE6.0-SP2下测试:
    keyDown:(17) :
    keyUp: (32) :
    keyUp:(17) :
    ——————————————————————————–
    keyDown:å(229) :
    keyUp:W(87) :
    ——————————————————————————–
    keyDown:å(229) :
    keyUp:Q(81) :
    ——————————————————————————–
    keyDown:å(229) :
    keyUp: (32) : 你
    ——————————————————————————–
    keyDown:å(229) : 你
    keyUp:V(86) : 你
    ——————————————————————————–
    keyDown:å(229) : 你
    keyUp:B(66) : 你
    ——————————————————————————–
    keyDown:å(229) : 你
    keyUp: (32) : 你好
    ——————————————————————————–
    onChange:你好

  15. Leon Says:

    快被这个问题弄晕了。最后非ie下设了一个计时器检测value,ie下用onkeyup解决的

  16. lone Says:

    能up就up,赫赫

  17. s79 Says:

    “每10秒执行一次回调函数。”
    应该是每10毫秒,10秒太长了。

  18. 李福拉 Says:

    onpropertychange别乱用啊…对象任何一个属性值变更了都会触发..包括样式….

  19. yzx99 Says:

    谢谢!

  20. 当键盘事件遇上输入法 - 浅析谷歌的一个Bug - 岁月如歌 Says:

    [...] Realazy的探索:http://realazy.org/blog/2007/10/31/solution-of-keyup-failing-when-ime-is-on/ [...]

Leave a Reply


realazy (懒到死) is proudly powered by WordPress | Entries (RSS) and Comments (RSS)