js防抖和节流

639 阅读2分钟
  • 前端开发中在处理 scroll resize input mousemove 等事件时,通常并不希望事件处理函数持续触发,防抖节流能更好的解决这一问题.
  • 为了便于演示持续触发事件的现象
<!-- html 代码 -->

<body>
  <input style="width: 100%; outline: none;" type="text">
  <div style="display: flex;">
    <div class="showThis" style="height: 100px;background: #eee;flex: 1;"></div>
    <div class="showEvent" style="height: 100px;background: rgb(179, 155, 155);flex: 1;"></div>
  </div>
  <script>
    let input = document.querySelector('input');
    let showThis = document.querySelector('.showThis')
    let showEvent = document.querySelector('.showEvent')
    
    input.oninput = valueChange
    
    function valueChange(e) {
      showThis.innerHTML = this.value
      showEvent.innerHTML = e.target.value
    }
   </script>
</body>

效果如下:

动画1.gif

如果在处理函数中执行一些更复杂的代码,比如 ajax 请求,那将造成性能消耗

防抖(debounce)

  • 所谓防抖,就是指触发事件单位时间后,才执行该事件的处理函数,如果在 单位时间内又触发了事件,则会重新计时,以保证事件里面的代码在单位时间只执行一次
// 防抖函数
function debounce(func, wait) {
  let timer = null
  return function () {
    const that = this
    const args = [...arguments]
    if (timer) clearTimeout(timer)
    timer = setTimeout(func.bind(this, ...args), wait)
  }
}
// 将事件处理函数用防抖函数处理
input.oninput = debounce(valueChange, 500)

此时效果:

动画2.gif

防抖的效果是只会执行最后一次触发的函数

节流(throttle)

  • 当事件触发之后,约定单位时间之内,事件里面的代码最多只能执行一次,所以,节流减少了单位时间内代码的执行次数,从而提高性能。。
// 节流函数
function throttle(func, wait) {
  let timer = null
  return function () {
    const that = this
    const args = [...arguments]
    if (timer) return
    timer = setTimeout(() => {
      timer = null
      func.apply(that, args)
    }, wait)
  }
}
// 将事件处理函数用节流函数处理
input.oninput = throttle(valueChange, 500)

此时效果:

动画3.gif

节流的效果是每隔单位时间会执行一次函数

总结

  • 防抖和节流都是为了解决频繁触发某个事件的情况造成的性能消耗。
  • 防抖就是在触发事件后的一段时间内执行一次,例如:在进行搜索的时候,当用户停止输入后调用方法,节约请求资源
  • 节流就是在频繁触发某个事件的情况下,每隔一段时间请求一次,类似打游戏的时候长按某个按键,动作是有规律的在间隔时间触发一次