当前位置: 首页 > Web前端 > HTML

输入事件触发中文的多个问题

时间:2023-04-02 19:37:03 HTML

我们经常会遇到网页实时搜索的情况,或者其他类似的需要实时响应输入的问题。一般我们使用input和propertychange事件来监听输入内容。变化来响应,但是有一个问题就是在输入汉字的时候,可能我们要输入'realtime'的时??候,我们的输入框里会出现'shishi',直到我们的空间变成'realtime',这也是的意思就是我们依次响应了's','sh','shi','shis','shish','shishi','realtime',前面的结果显然不是我们需要的,导致我们很多没用submissions,如果是接口请求,那就更要命了,已经发送了很多请求。  之前有一个稍微改进的解决方案,就是用定时器延迟执行,可以减少请求的数量,但是这个减少是分情况的,还是治标不治本。  今天偶然看到几个事件,发现这种问题可以完美解决。我们来看看这几个事件  compositionstart,compositionupdate,compositionend  compositionstart官方解释:在输入一段文字之前触发(类似于keydown事件,但是这个事件只是在输入之前几个可见字符,而这些可见字符的输入可能需要一系列的键盘操作,语音识别,或者点击输入法的备选词),简单的说,如果我们要输入一段中文,那就是当我们按下第一个字母时触发。  对应的compositionupdate触发我们中文从输入开始到结束的每一次keyup。  和compositionend当我们完成当前的中文输入时被触发。  话题来了。通过以上事件,我们就可以完美解决响应中文输入的问题了。从compositionstart的触发开始,意味着中文输入还没有完成,所以这个时候我们不需要响应。当compositionend被触发时,意味着中文输入完成,此时我们可以处理相应的事件。  所以我们可以给input设置一个变量,或者定义一个属性,在compositionstart和compositionend之间不响应input事件。看下面的代码.target.isNeedPrevent=true;},compositionend:function(e){e.target.isNeedPrevent=false;}})functionresponse(){$('div').append('

事件触发器

')}我们通过compositionstart和compositionend事件设置flag来判断是否正在输入中文来控制输入事件的响应。看似没有问题,但是在实际执行中,我们会发现GoogleChrome中input的执行顺序是在compositionend之前,Firefox的Executionsequence没问题,但是compositionend响应了两次。这会导致谷歌浏览器输入汉字不响应输入事件。当然你也可以在compositionend事件中再次执行response事件。这样做的问题是在火狐浏览器中响应会被多执行一次,这显然不是最优方案。  经过实验,我们发现keyup和compositionend事件在所有主流浏览器中的执行顺序都是一样的,所以我们改成如下代码:$('input').on({keyup:function(e){varflag=e.target.isNeedPrevent;if(flag)return;response()},compositionstart:function(e){e.target.isNeedPrevent=true;},compositionend:function(e){e.target.isNeedPrevent=false;}})functionresponse(){$('div').append('

Eventtrigger

')}这个跨浏览器基本一致(兼容compositionstart的浏览器)。但是keyup有问题。比如通过鼠标复制粘贴的时候,是不响应keyup事件的,所以我们需要对上面的东西进行优化。keyup对应按键事件,input响应keyup以外的change事件。代码如下,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;}})functionresponse(){$('div').append('

事件触发

')}最终效果的实现:在线预览: