如何在用户中止输入 JavaScript 后执行函数

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战html

咱们开发中可能常常会遇到这样的问题,咱们想要制做一个输入一个关键字,实时显示须要搜索的内容,但这会使你在每次触发事件时,都会执行你想要执行的筛选函数。但咱们只想在用户中止在文本框中键入文本后在执行搜索或过滤某些结果。这时,咱们应该怎么作呢?安全

这就要使用到今天要讲的防抖了,它的做用是:不管触发多少次事件,动做只会执行一次,也就是在必定程度的不活动以后执行函数。它的用处不少,好比上面这个问题。markdown

下面咱们完成上面的示例来加深印象。函数

示例:过滤文章

假设咱们的文档中有一个要筛选的文章的列表。咱们不但愿不断地执行 filter 函数,但只能在用户 “完成” 键入以后执行。由于咱们不知道用户何时完成了,因此咱们能够猜想,若是用户暂停一秒钟,咱们就能够安全地执行该函数(这可能因您的用例而异)。post

最终,咱们但愿效果以下:ui

过滤文章

HTML 结构以下:spa

<input type="text" class="article-filter" />
<ul class="article-list">
  <li>HTML</li>
  <li>JavaScript</li>
  <li>CSS</li>
  <li>Vue</li>
  <li>React</li>
  <li>Webpack</li>
</ul>
复制代码

如何工做?

防抖背后的思路是,咱们有一个全局 JavaScript 变量,该变量将保存对 setTimeout 的引用,用于清除全部未完成的计时器。code

而后,咱们的输入上有一个 keyup 事件监听器。当触发此事件时,咱们清除全局计时器(若是它正在运行)。这意味着计时器只有在指定的超时以前没有被清除时才会触发,换句话说,只有在超时以前没有 keyup 事件时才会触发!orm

let timer
const input = document.querySelector('.article-filter')
input.addEventListener(function (e) {
  // 清除全部未完成的计时器
  clearTimeout(timer)
  // 设置可能清除或不清除的新计时器
  timer = setTimeout(() => {
    // ...
  }, 1000)
})
复制代码

完整示例

如今,咱们大概的结构已经出来了,咱们将遍历 .article-list 元素的全部 children,并相应地更新 style.display 属性。htm

let timer
const input = document.querySelector('.article-filter')
input.addEventListener('keyup', function (e) {
  // 清除全部未完成的计时器
  clearTimeout(timer)
  // 设置可能清除或不清除的新计时器
  timer = setTimeout(() => {
    const items = document.querySelector('.article-list').children
    for (let item of items) {
      item.style.display = item.textContent.includes(e.target.value)
        ? 'list-item'
        : 'none'
    }
  }, 1000)
})
复制代码

注意:以上示例须要区分大小写。

相关文章
相关标签/搜索