Javascript 搜索延迟并从事件监听器收集输入

Javascript search delay and collect input from eventlistener

我有一个简单的输入框。当我写东西时,我希望它被延迟。我遇到的问题是在非常快地写入字符时出现延迟后,它多次调用 console.log。

现在发生了什么

我输入 a 并等待。然后我快速输入 b c d 并等待。然后e f快等。它赶上了我不想要的。我希望它收集我输入的内容,但在延迟完成之前不输出它。

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">

解决方案及分步说明

所以你需要debounce

下面的代码显示了只有当两次击键之间的时间差至少为 2 秒时才执行函数。

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>

您的预期行为类似于 debounce

在我看来你应该 clearTimeout 在创建新的之前。

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);
  • 消除
  • 主题演讲: 运算符跟踪最新值。

阅读 post "throttleTime vs debounceTime in RxJS" 以详细了解。