这是我参与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)
})
复制代码
注意:以上示例须要区分大小写。