Reputation: 171
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
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