input事件中文触发多次问题研究

我们在网页中经常会遇到实时搜索的情况,或者其他类似需要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://www.cnblogs.com/jlfw/p/12036810.html

时间: 2024-11-04 13:22:43

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

即时搜索:对于ios自带输入法输入中文时多次触发input事件的处理

实现移动端的即时搜索的最佳方案,一定是使用input propertychange事件了,但是在ios设备上遇到了问题,使用ios自带输入法输入汉字时,会出现多次触发input事件的情况,一开始可能由于搜索的关键字不得法,没有即时找到合适的方案,后来终于在网上找到了解决方案,现记录如下: 代码实现 /** * @param flag: 用于标记是否是非直接的文字输入 */ var flag = false; $('#id').on({ 'compositionstart': function()

移动端开发注册、登陆input常用事件(input输入文字触发事件)

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>移动端开发注册.登陆input常用事件(input输入文字触发事件)</title> <meta name="keywords" content="

INPUT[type=file]的change事件不触发问题

在网页上要操作文件通常会使用INPUT[type=file]控件,但这个控件的设计很蛋疼.它不像其它编程语言中文件选择后会触发一个事件,只是让上面的文字改变,而这个改变可能会触发change事件而已.对于文字没改变的选择,change事件则不会触发. 当INPUT[type=file]控件上已经选择过一次文件之后,再次点击它选择同一个文件时change事件就不会触发.因为第二次选择后里面的文字和第一次是一样的,没有改变.还有个更蛋疼情况是有些浏览器会自动记住控件上的文字,即使页面关闭后重新打开还

在谷歌浏览器下vue的@input事件问题

在谷歌浏览器下vue的@input事件问题:input输入中文,在输入拼音的时候就在触发(360不这样) 原文链接:https://blog.csdn.net/m0_37817986/article/details/103079249 <input v-on:input="searchOne($event,item.ind)" v-on:compositionstart="flagg=false" v-on:compositionend="flagg

jQuery中让点击事件只触发一次($(&quot;&quot;).one(&quot;click&quot;,function(){});)

有时候该按钮要求只能进行一次点击操作,又不想通过代码逻辑来处理,判断次按钮是否被触发过,就可以用这个小技巧来写 jQuery代码 $(function () { $(":button").one("click", function () { //事件只触发一次 alert("dianle") }); }); <body> <input type="button" value="click"

HTML5 input事件检测输入框变化

之前一直用change事件来监听输入框内容是否发生变化,只有当输入框失去焦点时才会触发,没想到html5还有个input事件,只要输入框内容发生变化就会立即触发,既然有这么好的东西我们干嘛放着不用呢,接下来就来给大家介绍一下: 如果我们页面上有这样一个简单到极致的输入框: 1 <input type="text"> 那么我们现在用jquery给它绑定input事件,如下: 1 $("input:text").bind("input proper

Android4.0 input事件输入流程详解(中间层到应用层)

在Android系统中,类似于键盘按键.触摸屏等事件是由WindowManagerService服务来管理的,然后再以消息的形式来分发给应用程序进行处理.系统启动时,窗口管理服务也会启动,该服务启动过程中,会通过系统输入管理器InputManager来负责监控键盘消息.当某一个Activity激活时,会在该Service下注册一个接收消息的通道,表明可以处理具体的消息,然后当有消息时,InputManager就会分发给当前处于激活状态下的Activity进行处理. InputManager的启动

再谈multistage text input(中文输入法)下UITextView的内容长度限制

之前写过一篇<如何更好地限制一个UITextField的输入长度>,在文章最后得到的结论是可以直接使用 UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification; 进行监听,截断超出maxLength的部分. 所以后来我在处理UITextView的内容长度时,也直接参考这个方法: [[NSNotificationCenter defaultCenter] addObserver:self selector:@select

如何用按钮的click事件去触发a标签的click事件

在jQquery中,可以用如下方式触发input.a标签的click事件: <input id="my_input" /> <a id="my_a" href="http://www.XXXX.html"></a> $("#my_input").click(function () { //do something }); 或 $("#my_a").click(functi