Monitor if the change event occurred in a short time

Asked

Viewed 73 times

0

I have in my framework a trigger that sends the data from input onchange for a model that validates and returns, in this process there is a problem, each character typed is made a submission, what I’m trying to do is the function described below (I don’t want to use socket for this while):

When there is a change in the value of the input check if there has been another change within 0.5 seconds, if there is no trigger, if there is to wait another 0.5 to fire check if there has been another change and so on.

So far I’ve come to that:

$(document).on('change keyup','input',function(e){
        var $this = $(this);
	e.preventDefault();
        var text = $this.val();
	        setTimeout(function(){
                var text2 = $this.val();
                if(text !== text2){
                    //dispara o mesmo evento de novo
                    console.log('houve mudança de :'+ text + 'para: ' +text2);
                }else{
                   //dispara algum função
                   console.log('manteve o valor de: '+text);
                }
            }, 500);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text'>

Apparently this is working, what I want to know is:

  • This is not actually accumulating events shot into it
    Trigger ?

1 answer

2


Yes, it will accumulate events.

As with each change and pressed key you schedule the execution of a function with setTimeout, you can press several keys before this interval ends, and in each key a new scheduling is created. At the end, on the console you will see a flood of similar messages after the end of the first interval.

What to do?

For you to fire the event after certain time only after the last key, you need to cancel the previous timeout and release another:

$(function() {
  $(document).on('change keyup', 'input', function(e) {
    var $this = $(this);
    e.preventDefault();
    var text = $this.val();
    // verifica se o elemento já agendou a execução da função pelo setTimeout
    var timeoutId = $this.data('timeoutId');
    console.log('this.value antes do setTimeout', text);
    console.log('timeoutId inicial', timeoutId);
    // já temos algum agendamento?
    if (timeoutId !== undefined) {
      console.log('clearing timeoutId', timeoutId);
      // cancela o agendamento feito anteriormente
      clearTimeout(timeoutId);
    }
    // agenda a função e guarda o valor retornado
    timeoutId = setTimeout(function() {
      var text2 = $this.val();
      console.log('texto agora', text2);
      console.log('manteve o valor?', text === text2);
      // remove o dado do elemento após a execução
      $this.removeData('timeoutId');
    }, 1000);
    console.log('timeoutId retornado de setTimeout', timeoutId);
    // guarda o valor retornado do setTimeout no próprio elemento
    $this.data('timeoutId', timeoutId);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="" placeholder="digita alguma coisa aqui..." />

I filled with comments and log, but the comments of the scheduled function only appear after passing the interval counting from the last event.

More information

Browser other questions tagged

You are not signed in. Login or sign up in order to post.