2010年6月19日星期六

2010/5/13 Javascript实现输入内容变化的监控通知

目前做个即时通讯的web客户端,类似于Web QQ。我们使用qq、msn时,经常会看到“对方正在打字”的提示,这样就知道对方正在输入一些东西。实现就是当用户做出一些改变的时候,向对方发送一个通知信息。至于如何定义什么时候发这个通知,则由客户端实现自己决定。一般就是监测用户的键盘事件或输入内容的变化。

实现目标:当用户在输入框中输入或改变了一些内容时,发送一个通知。
起初的简单实现:监听浏览器中输入框的 keypress 事件。因为不应该每一个改变都应该立刻发送通知,那样过于频繁了,所以设置一个计数器counter,counter大于一个值(比如3)才是发送通知,再把counter设为0。

除了常规输入(输入字符和数字)外,用户按下Backspace和Delete键时会怎样?自己测试时发现一些问题:
keypress 事件在按下非字符键时,有些键会触发,有些键不会触发,而且具体随浏览器还不同。比如在ie中,仅字符键会触发keypress,那就是说你在IE上按Backspace删除了很多内容时,也不会发通知,因为没有触发keypress事件,而我的目标是应该发送通知。但在 Firefox 上就会触发keypress事件,也就是会发送通知。
一种解决方式是,你需要在specialKey中单独监控Backspace键,就可以在不同浏览器上都监控好。
但是我发现同样的方法监控不到Delete键。

后来又发现中文输入法也会干扰正常的事件,影响我目标的实现。
在输入中文时,在输入法窗口中显示了很多字,但只会产生一个keypress事件,这是正常的。但这样我原来的简单实现就没有很好地达到我的目的。而这时不应该仅靠事件触发的次数,还应该看每次事件时,字数变化的多少。

而且不同的输入法的兼容性和不同的浏览器实现都会有影响。
比如在IE上,使用谷歌拼音输入法,按数字键或输入中文,虽然都正常输入了,但都不会产生事件,而用智能abc输入中文没有事件,输入数字有事件;
而在Firefox上,使用谷歌拼音输入法,事件都是正常的。

小结:不同浏览器的键盘事件的处理有差异,同时中文输入法事件也有影响,并且还是二者交错的,比较复杂。
可以采用另一种方法绕开浏览器事件差异、中文输入和输入法兼容的影响,而实现我们原本的目的:
在浏览器上采用 timer 的方式,比如每隔0.5秒检查一下输入框中的内容变化,只根据内容的变化情况决定是否发送通知(据说Google搜索的自动补全就是这样做的)。
比如记录上次发送通知时输入框的内容(lastInput),每隔0.5秒查看当前内容(currentInput)与 lastInput 的长度之差的绝对值是否大于3。

参考资料:
JavaScript Madness: Keyboard Events:http://unixpapa.com/js/key.html
从谷歌的一个Bug说起,谈谈键盘事件的兼容性:http://www.javaeye.com/topic/233038

没有评论: