This is the 9th day of my participation in the August More Text Challenge

One of the things that we often run into in development is that we want to make an input keyword that shows you what to search for in real time, but this will cause you to perform the filter function that you want to perform every time you trigger an event. But we only want to perform a search or filter some results after the user stops typing text into the text box. What should we do at this point?

This brings us to today’s anti-shake, which means that no matter how many events are triggered, the action will only be executed once, after a certain amount of inactivity. It has many uses, such as the one above.

Let’s finish the example above to impress.

Example: Filter articles

Suppose we have a list of articles to filter in our document. We do not want the filter function to be executed continuously, but only after the user has “finished” typing. Since we don’t know when the user is finished, we can guess that if the user pauses for a second, we can safely execute the function (this may vary depending on your use case).

Ultimately, we want this:

The HTML structure is as follows:

<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>
Copy the code

How does it work?

The idea behind stabilization is that we have a global JavaScript variable that will hold a reference to setTimeout, which will be used to clear all outstanding timers.

Then, we have a keyUp event listener on our input. When this event is triggered, we clear the global timer if it is running. This means that the timer fires only if it has not been cleared before the specified timeout, in other words, only if there are no keyUp events before the timeout!

let timer
const input = document.querySelector('.article-filter')
input.addEventListener(function (e) {
  // Clear all outstanding timers
  clearTimeout(timer)
  // Sets new timers that may or may not be cleared
  timer = setTimeout(() = > {
    // ...
  }, 1000)})Copy the code

Complete sample

Now that we have our general structure out, we’ll iterate through all children of the.article-list element and update the style.display attribute accordingly.

let timer
const input = document.querySelector('.article-filter')
input.addEventListener('keyup'.function (e) {
  // Clear all outstanding timers
  clearTimeout(timer)
  // Sets new timers that may or may not be cleared
  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)})Copy the code

Note: The above example needs to be case sensitive.