Monitor if the change event occurred in a short time

0

I have in my framework a trigger that sends the data of input onchange to a model that validates and returns, in that process has a problem, each character typed is made a submission, what I'm trying to do is the function described below (I do not want to use socket for this for now):

  

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 a further 0.5 wait to trigger check if there has been another change and so on.

So far I've come to this:

$(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 actually not accumulating events triggered in the same
      trigger?

asked by anonymous 25.10.2017 / 17:09

1 answer

2

Yes, you will accumulate events.

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

What to do?

To trigger the event after a certain time only after the last key , you need to cancel the previous timeout and launch 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><inputtype="" placeholder="digita alguma coisa aqui..." />

I filled in comments and logging, but comments on the scheduled function only appear after passing the interval counting from the last event.

More information

25.10.2017 / 20:33