這是我參與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)
})
複製代碼
注意:以上示例須要區分大小寫。