阅读 413

防抖和节流

一. 防抖(debounce)

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
复制代码

简单来说防抖就是如何有个点击事件,假设防抖间隔为2s,那点击一次后得2s后点击第二次才能有效,在2s内的点击都会使计时器重新计时。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>防抖函数实现</title>
</head>

<body>
  <button id="btn">点击</button>
  <script>
    var oBtn = document.getElementById('btn')
    /**
 *
 * @param {*} func[function] 要执行的方法
 * @param {*} wait[number] 等待执行的时间(用户自己规定多长时间内不算频繁的操作)
 * @param {*} immediate  疯狂点击的时候最终只识别一次,识别第一次还是最后一次,immediate为true,立即执行(第一次)
 * @return 可以被调用执行的函数
 */
    function myDebounce(handle, wait = 300, immediate = false) {
      let timer = null
      return function (...res) {
        let first = immediate && !timer
        clearTimeout(timer)
        timer = setTimeout(() => {
          // 手动让其回归到初始状态(下一轮开始还是从timer为null开始),没加这句,只会执行一次,就没有了
          timer = null
          !immediate && handle.apply(this, res)
        }, wait)

        first && handle.apply(this, res)
      }
    }

    // 定义事件执行函数
    function btnClick(ev) {
      console.log('点击了1111', this, ev)
    }

    // oBtn.onclick = btnClick  // this ev


    oBtn.onclick = myDebounce(btnClick, 2000, true)

  </script>
</body>

</html>
复制代码

二. 节流(throttle)

规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

还是以2s间隔为例,节流是点击之后2s后在点击也一定会执行,就算2s内你一直点也会。但防抖不会,防抖是要求你点击之后2s内不能在点击了,否则计时无效。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>节流函数实现</title>
</head>

<body>
  <button id="btn">点击</button>
  <script>
    var oBtn = document.getElementById('btn')
     // 节流:我们这里的节流指的就是在自定义的一段时间内让事件进行触发
    /**
     * 函数节流:在一段频繁操作中,可以触发多次,但是触发的频率由自己指定
     * @param {*} func[function]:最后要触发执行的函数
     * @param {*} wait[number]:触发的频率
     */
     function myThrottle(fn, wait) {
     let lastTime = 0 ;
     return function(...res){
       let now  = new Date()
      if(now-lastTime>wait){
        lastTime = now
        fn.apply(this,res)
      }
     }
    }

    // 定义事件执行函数
    function btnClick(ev) {
      console.log('点击了1111', this, ev)
    }

    // oBtn.onclick = btnClick  // this ev


    oBtn.onclick = myThrottle(btnClick, 2000)

  </script>
</body>

</html>
复制代码

三. 应用场景

  • 防抖

    search搜索联想,用户在不断输入值时,用防抖来节约请求资源。

    登录、发短信等按钮避免用户点击太快,以致于发送了多次请求。

    调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多。

    文本编辑器实时保存,当无任何更改操作一秒后进行保存。

  • 节流

    scroll 事件,每隔一秒计算一次位置信息等。

    浏览器播放事件,每个一秒计算一次进度信息等。

文章分类
前端
文章标签