我们在网页中经常会遇到实时搜索的情况,或者其他类似需要input实时响应的问题,一般情况下,我们是利用input和propertychange事件来监听input内容的变化来响应,但是有一个问题就是当输入汉字的时候,可能我们要输入 ‘实时’ 的时候,我们的input框中会出现 'shishi'直到我们的空格才会变成 '实时',这也就意味着我们依次响应了 's','sh','shi','shis','shish','shishi','实时',前面的结果明显不是我们需要的 ,造成了我们很多次无用的提交,如果是接口请求,那更要命,多发了好多次请求。

  最早之前有一个稍微能改善的解决方案就是配合一个定时器延时执行,这样能减少请求次数,但是这个减少是不分情况的减少 ,还是治标不治本。

  今天偶然看到几个事件,发现可以完美解决这种问题。我们来看一下这几个事件

  compositionstart , compositionupdate ,compositionend  

   compositionstart 官方解释 : 触发于一段文字的输入之前(类似于 keydown 事件,但是该事件仅在若干可见字符的输入之前,而这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词),通俗点,假如我们要输入一段中文,当我们按下第一个字母的时候触发 。

  相应的compositionupdate在我们中文开始输入到结束完成的每一次keyup触发。

  而compositionend则在我们完成当前中文的输入触发 。

  正题来了,通过上面的事件我们就可以完美的解决中文输入的响应问题了,从compositionstart触发开始,意味着中文输入的开始且还没完成,所以此时我们不需要做出响应,在compositionend触发时,表示中文输入完成,这时我们可以做相应事件的处理。

  所以我们可以设置一个变量,或者给input定义一个属性,在compositionstart到compositionend之间对input事件不做出响应。看以下代码

$('input').on({
input : function(e){
var flag = e.target.isNeedPrevent;
if(flag) return;
response()
},
compositionstart : function(e){
e.target.isNeedPrevent = true ;
},
compositionend : function(e){
e.target.isNeedPrevent = false;
}
})
function response(){
$('div').append('<p>事 件触发</p>')
}

  我们通过compositionstart,compositionend事件来设置flag,判断是否正在进行输入中文以控制input事件的响应,看上去没有问题,但实际执行时会发现在谷歌浏览器中input执行顺序要先于compositionend,火狐执行顺序正常,但compositionend会响应两次。这就导致谷歌浏览器中输入汉字不会响应input事件。当然也可以在compositionend事件中再执行一次response事件,这样的问题是在火狐浏览器中会多执行一次response,显然不是最优方案。

  经过试验,发现keyup和compositionend事件执行顺序在各大浏览器都保持一致,于是我们改成如下代码:

$('input').on({
keyup : function(e){
var flag = e.target.isNeedPrevent;
if(flag) return;
response()
},
compositionstart : function(e){
e.target.isNeedPrevent = true ;
},
compositionend : function(e){
e.target.isNeedPrevent = false; }
})
function response(){
$('div').append('<p>事 件触发</p>')
}

  这样在各个浏览器基本保持一致了(兼容compositionstart的浏览器)。但是keyup有一个问题,比如通过鼠标复制粘贴的时候并不相应keyup事件,所以上面的事情我们还需要再优化下,keyup相应按键事件,input响应除了keyup之外的变化事件。代码如下

$('input').on({
keyup : function(e){
var flag = e.target.isNeedPrevent;
if(flag) return;
response() ;
e.target.keyEvent = false ; },
keydown : function(e){
e.target.keyEvent = true ;
},
input : function(e){
if(!e.target.keyEvent){
response()
}
},
compositionstart : function(e){
e.target.isNeedPrevent = true ;
},
compositionend : function(e){
e.target.isNeedPrevent = false; }
})
function response(){
$('div').append('<p>事 件触发</p>')
}

  从目前需求可以完全实现了。

在线预览:

参考文章:

https://developer.mozilla.org/zh-CN/docs/Web/Events/compositionstart

  

input事件中文触发多次问题研究的更多相关文章

  1. input输入中文时,拼音在输入框内会触发input事件的问题。

    问题描述: 监听文本输入框的input事件,在拼写汉字(输入法)但汉字并未实际填充到文本框中(选词)时会触发input事件,如图: 需要完成的需求就是在输入阶段不触发input中的事件,选词之后文字落 ...

  2. input、textarea等输入框输入中文时,拼音在输入框内会触发input事件的问题

    监听文本输入框的input事件,在拼写汉字(输入法)但汉字并未实际填充到文本框中(选词)时会触发input事件,如图: 但是在很多情况下,只需要输入到输入框的中文字符. 解决办法: 通过查阅资料得知在 ...

  3. input事件以及中文输入法的处理

    在项目的开发过程中,相信大家都处理过监听用户输入的事情,一般我们会用到onkeyup.onkeydown.onkeypress.onchange.oninput事件,虽然都很熟悉了,但是还是有必要巩固 ...

  4. compositionEnd 和 input 事件(中文输入法问题)

    网上用 compositionstart + compositionend + input 解决中文输入法问题的办法 node.addEventListener('compositionstart', ...

  5. label标签内含有input元素,点击事件会触发两次

    **label标签内含有input元素,点击事件会触发两次** 如果你的结构是label内写input实现点击文字时候input也有相应.并且,把事件设置在了label上,那么就会执行两次了. //h ...

  6. vant 使用field组件加载页面就触发input事件的坑,已解决

    使用vant的时候,遇到一个坑,加载组件就自动触发input事件,input事件里写了验证,导致已加载就验证错误 原因:v-model绑定的时候写的是null, filed组件接收的时候把他转换成空字 ...

  7. input 事件与汉字输入法:使用compositionend事件解决

    input 事件与汉字输入法:使用compositionend事件解决 在使用<input type="text">的input事件的时候 会遇到中文输入法的" ...

  8. input事件与change事件

    输入框的change事件: 必须等到输入框失去焦点的时候才会触发,鼠标在空白的地方点一下: 输入框的input事件: 在输入内容变化的同时,实时的触发,不需要等到失去焦点.

  9. HTML5 input事件检测输入框变化

    之前一直用change事件来监听输入框内容是否发生变化,只有当输入框失去焦点时才会触发,没想到html5还有个input事件,只要输入框内容发生变化就会立即触发,既然有这么好的东西我们干嘛放着不用呢, ...

随机推荐

  1. 《Django By Example》Chap 4中出现的 “RelatedObjectDoesNotExist”错误

    models.py

  2. 微信公众号H5支付遇到的那些坑

    简史 官方文档说的很清楚,商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程. 当然,最近微信支付平台也加入了纯H5支付,也就是说用户可以在微信以外的 ...

  3. Android开发之漫漫长途 IX——彻底掌握Binder

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  4. sourcetree跳过注册的方法

    当前只有Win的版本,Mac自行百度(笑) 很多人用git命令行不熟练,那么可以尝试使用sourcetree进行操作. 然鹅~~sourcetree又一个比较严肃的问题就是,很多人不会跳过注册或者操作 ...

  5. 序列化之对象,字符串,byte数组,XML之间的转换(一)

    工作一年多了,越来越感到自己不能这样一直下去,在最好的青春里面却已经死了.被时间消磨了意志,被工作杀死了精神.我想,我只要活着,我就要去不断的要求自己,不断的去追求更高的山峰. 放眼四周,有趣的灵魂越 ...

  6. FPGA 设计总结(1)

    1. set_input_delay和set_output_delay的选项-max和-min的理解 首先 input/output其实是模拟数据在端口外的延时,是一个外部约束条件,目的是为了约束FP ...

  7. Effective Java 第三版——13. 谨慎地重写 clone 方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. h5拖拽上传图片

    h5实现拖拽上传图片 本文将为大家介绍如何通过js实现拖拽上传图片. 首先我们要禁用调浏览器默认的拖拽事件: window.onload = function(){ //拖离 document.add ...

  9. 朴素的treap

    所谓Treap,就是一种二叉查找树,而我们知道二叉查找树,相对来说比较容易形成最坏的链表情况,所以我们有一种数据结构来防止二叉查找树出现最坏情况,那就是Treap. Treap=tree+heap,T ...

  10. 初识BASH SHELL

    什么是Shell shell翻译成中文就是"壳"的意思.简单来说就是shell是计算机用户与操作系统内核进行"沟通"的一种工具.Windows系统中有power ...