Reputation: 24778
I have a simple input box. When I write something, I want it to be delayed. The problem I have is after the delay when writing characters very fast it calls the console.log multiple times.
I type a
and wait. Then I type b c d
fast and wait. Then e f
fast and wait. It catches up which I don't want. I want it to collect what I type, but not output it until the delay is done.
a
.
.
.
b c d
b c d
b c d
.
.
.
e f
e f
a
.
.
.
b c d
.
.
.
e f
var searchtimer;
window.addEventListener("DOMContentLoaded", () => {
document.querySelector("#search").addEventListener("input", (e) => {
searchtimer = setTimeout(() => {
console.log(e.target.value);
clearTimeout(searchtimer);
}, 1000);
});
});
<input id="search" type="text">
Upvotes: 6
Views: 3853
Reputation: 391
Solution with step by step explanation
So you need to debounce.
The below code shows how a function is executed only when the time difference between 2 keystrokes is at least 2 seconds.
let count=0;
//If we call this directly from the HTML, the function will be
// fired for every click, which hinders the performance
let myFunction =()=>{
document.querySelector("#demo").innerHTML = "Hello World "+ ++count ;
}
//So we'll call this debouncing wrapper function from the HTML instead
let myFunc=letsDebounce(myFunction,2000);
//The wrapper calls setTimeout to execute its argument fn after
// the specified delay, but if the triggering event fires again
// before the setTimeout duration finishes, then the timer gets reset
// so the previous call is ignored
function letsDebounce(fn,d){
let timer;
return function(){
clearTimeout(timer);
timer=setTimeout(fn,d);
}
}
<button onclick="myFunc()">Debounce</button>
<p id="demo"></p>
Upvotes: 2
Reputation: 14228
Your expected behavior looks like debounce
.
It seems to me that you should clearTimeout
before creating the new one.
var searchtimer;
window.addEventListener("DOMContentLoaded", () => {
document.querySelector("#search").addEventListener("input", (e) => {
clearTimeout(searchtimer); // <--- The solution is here
searchtimer = setTimeout(() => {
console.log(e.target.value);
}, 1000);
});
});
<input id="search" type="text">
clearTimeout(searchtimer);
Read post "throttleTime vs debounceTime in RxJS" to understand in detail.
Upvotes: 7