Skip to content

手写防抖节流

约 647 字大约 2 分钟

防抖节流js进阶

2025-05-05

防抖的核心是 延迟执行,在事件频繁触发时,只有最后一次触发后的指定时间内没有新事件,才会执行目标函数

只执行最后一次

利用延时器

举例:在一个盒子中移动,只有最后一次间隔500ms才增加数字

  • 利用第三方库 lodash

    import _ from 'lodash'
    // 在盒子里面移动数字加一
        //不想一移动就增加,防抖优化--- 移动后500毫米加_.debounce
        const box = document.querySelector('.box')
        let i = 1
        function mouseMove() {
          box.innerHTML = i++
        }
    
        box.addEventListener('mousemove', _.debounce(mouseMove, 500))
  • 手写防抖

主要思想:移动后看有无定时器,有就关闭上一个,再开一个,没有就开

// 在盒子里面移动数字加一
    //不想一移动就增加,防抖优化--- 移动后500毫米加_.debounce
    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
      box.innerHTML = i++
    }

    // box.addEventListener('mousemove', mouseMove)
    // box.addEventListener('mousemove', _.debounce(mouseMove, 500))

    //手写防抖
    //主要思想,移动后看有无定时器,有就关闭上一个,再开一个,没有就开

    function debounce(fn, t) {

      let time
      return function () {//为什么要返回一个函数,用为调用的地方函数时加括号的,页面一加载就用了,必须给返回匿名函数,一直用
        if (time) clearTimeout(time)//有关闭
        time = setTimeout(function () {
          fn()
        }, t)
      }
    }

    box.addEventListener('mousemove', debounce(mouseMove, 500))

2. 节流

节流的本质是 固定频率执行,无论事件触发多频繁,目标函数在指定时间间隔内最多执行一次

间隔某一时间执行

  • 利用第三方库 lodash

     
    import _ from 'lodash'
    // 在盒子里面移动数字加一
        //不想一移动就增加,节流优化--- 500毫米只执行一个事件_.throttle
        const box = document.querySelector('.box')
        let i = 1
        function mouseMove() {
          box.innerHTML = i++
        }
    
    
        //1.库
        box.addEventListener('mousemove', _.throttle(mouseMove, 500))
  • 手写节流

主要思想:移动后看有无延时器,有就不管,等待延时器执行,没有就开启一个

 // 在盒子里面移动数字加一
    //不想一移动就增加,节流优化--- 500毫米只执行一个事件_.throttle
    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
      box.innerHTML = i++
    }


    //1.库
    box.addEventListener('mousemove', _.throttle(mouseMove, 500))

    //手写节流
    function throttle(fn, t) {

      let time = null
      return function () {//为什么要返回一个函数,用为调用的地方函数时加括号的,页面一加载就用了,必须给返回匿名函数,一直用
        if (!time) {//没有创建
          time = setTimeout(function () {
            fn()
            //关闭
            time = null
          }, t)
        }
      }

    }
    box.addEventListener('mousemove', debounce(mouseMove, 500))