函数防抖和节流

197 阅读1分钟

函数防抖和节流,都是控制事件触发频率的方法。应用场景包括:输入框持续输入,多次触发点击事件等。

函数防抖

持续触发不执行,不触发的一段时间之后再执行

场景:鼠标滑过一个div,触发onmousemove事件,就会在控制台打印出对应的坐标;

<body>
<div id="ba"></div>
</body>

<style>
  #ba {
      width: 500px;
      height: 500px;
      background: #ccc;
      line-height: 500px;
    }
</style>

<script>
 const box = document.getElementById('ba')
  box.onmousemove = debounce(function (e) {
   console.log( `${e.clientX}, ${e.clientY}`)
  })
</script>

打印结果

移动鼠标瞬间,控制台打印出多组坐标,如果不想频繁的触发onmousemove事件,在最后一次触发的2s后打印该点坐标。需要用到函数防抖、节流

防抖实现方法:设置一个定时器实现一段时间后开始执行,持续触发不执行(将定时器清除),函数封装如下。

 function debounce(fn, delay){
     let timerId = null
     return function(){
         const context = this
         if(timerId){window.clearTimeout(timerId)}
         timerId = setTimeout(()=>{
             fn.apply(context, arguments)
             timerId = null
         },delay)
     }
 }

用法

  const 打印= debounce((content)=>{
    console.log(content)
  },2000)
  const box = document.getElementById('ba')
  box.onmousemove = function(e){
    console.log('连续触发不执行')
    打印(`触发暂停2s,坐标为:${e.clientX}, ${e.clientY}`)
  }

效果

总结:防抖就是连续触发的时候不会执行该函数,触发一段时间后开始执行该函数。

节流

连续触发不会执行,在固定的时间内去执行

函数封装如下

 function throttle(fn, delay){
     let canUse = true
     return function(){
         if(canUse){
             fn.apply(this, arguments)
             canUse = false
             setTimeout(()=>canUse = true, delay)
         }
     }
 }

用法

  const 打印= throttle((content)=>{
    console.log(content)
  },2000)
  const box = document.getElementById('ba')
  box.onmousemove = function(e){
    console.log('时间没到,不打印')
    打印(`2s已到,坐标为:${e.clientX}, ${e.clientY}`)
  }
  

结果看出:无论2s内触发多少次都不会执行,只会在那一刻才会执行

总结:节流更像是玩游戏的cd技能,只能在固定的时间内释放该技能,如果技能在冷却中就不会触发该技能。