user2315641
user2315641

Reputation: 171

Delay execution of a setTimeout() function until user stops typing

I'm trying to create a small function that runs every minute, but if the user is still typing when the function is to be executed, delay the execution until the user stops typing.

I have read this and other relevant questions, but my problem is different in that it includes an already scheduled function execution through setTimeout()

I have tried resetting the timer if the user is still typing, but this only forces the function to run again multiple times.

var timer = null

runTimer()

$('body').on('keyup', ':input', function(e) {
    timer = setTimeout(runTimer, 400);
});

$('body').on('keydown', ':input', function(e) {
    clearTimeout(timer);
});

function runTimer() {
    setTimeout(function(){
        executeFunction();
    }, 60 * 1000);
}

function executeFunction() {
    console.log('Ran function')
    setTimeout(function(){
        executeFunction();
    }, 60 * 1000);
}

I want the function to be executed once every minute, delayed until user stops typing but reset the timer to one minute after being executed. Also using underscore.js is acceptable.

Upvotes: 0

Views: 350

Answers (1)

yqlim
yqlim

Reputation: 7118

You can use a isTyping variable to check whether any key is pressed, with setInterval to wait for isTyping to become false. When isTyping is false, run your function.

Something like this:

You can test by typing in the input fields. When you long press a key, the execution will stop and resume immediately when you release the key.

var isTyping = false;
var interval = null;

var count = 0; // demo only

$('body').on('keyup', ':input', function(e) {
    isTyping = false;
});

$('body').on('keydown', ':input', function(e) {
    isTyping = true;
});


runTimer();


function executeFunction(){
  console.log('Execute', count++);
  runTimer();
}

function runTimer(){
  // I change to 1 second for easy testing
  setTimeout(runExecute, 1 * 1000);
}

function runExecute(){
  /**
   * If not typing
   *   clear interval
   *   execute function
   * else, if interval is not set
   *   set interval
   * else
   *   do nothing, wait for user stop typing
   */
  if (isTyping !== true){
    clearInterval(interval);
    interval = null;
    executeFunction();
  } else if (!interval){
    interval = setInterval(runExecute, 4);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input>

Note

Using keyup and keydown alone, isn't a good way to check whether a user is typing. See this question for a better implementation to check user typing.

Upvotes: 1

Related Questions