Skip to content

防抖节流

Lodash是一个JavaScript实用工具库,提供了许多常用的函数和工具,能够方便地处理集合、字符串、数值、函数等多种数据类型,减少编写重复代码的时间和精力。Lodash的API设计与ES6的新特性相似,同时兼容了更早的浏览器版本。Lodash支持模块化加载,可以通过npm或在浏览器中直接引入来使用。

Lodash有超过300个函数,每个函数都有详细的文档和示例,能够快速地满足各种编程需求。同时,Lodash的功能也非常完善,比如数组、对象等的操作,以及日期、数学计算、函数式编程等多方面支持。Lodash还提供了链式调用的方式,简化操作的流程。

因此,Lodash能够大幅度提高前端JavaScript编程的效率和可读性,使得代码编写更加快捷、简洁、易懂。

lodash中文官方文档:https://www.lodashjs.com/

  1. 防抖(debounce) 所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

    loudash库实现防抖:

    html
    <body>
      <div class="box">
        <p></p>
      </div>
      <script src="./lodash.js"></script>
      <script>
        let i = 0
        p = document.querySelector('p')
        box = document.querySelector('.box')
          
        function mouseMove () {
          p.innerHTML = i++
        }
    
        // 利用loudash库实现防抖 - 500毫秒之后执行一次
        box.addEventListener('mousemove', _.debounce(mouseMove, 500))
      </script>
    </body>

    底层实现原理:

    js
    function debounce(fn, t) {
        let timer
        // 返回一个匿名函数
        return function() {
            // 如果计时器存在,就清空计时器
            if(timer) clearTimeout(timer)
            timer = setTimeout(function(){
                fn()
            }, t)
        }
    }
  2. 节流(throttle) 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。

    使用场景:高频事件,如鼠标移动、尺寸缩放、滚动条滚动等。

    loudash库实现防抖:

    _throttle函数默认就是会调用两次。分别是第一次和最后一次。如果想要throttle函数只会调用一次,可以设置options.trailing=false。这样函数的表现就像普通的截流函数了。

    html
    <body>
      <div>
        <p></p>
      </div>
      <script src="./lodash.js"></script>
      <script>
        let i = 0
        p = document.querySelector('p')
        div = document.querySelector('div')
    
        function mouseMove () {
          p.innerHTML = i++
        }
    
        // 利用loudash库实现防抖 - 500毫秒之后执行一次
        div.addEventListener('mousemove', _.throttle(mouseMove, 1000, { 'trailing': false }))
      </script>
    </body>

    底层实现原理:

    js
    function throttle(fn, t) {
        let timer = null
        // 返回一个匿名函数
        return function() {
            // 如果计时器不为null,不触发函数
            if(!timer) {
                timer = setTimeout(function() {
                    fn()
                    // 计时器触发才把timer置为null
                    timer = null
                }, t)
            }
        }
    }

节流综合案例 —— 记录视频播放位置存储

js
// 1. 获取元素  要对视频进行操作
const video = document.querySelector('video')
video.addEventListener('timeupdate', _.throttle(() => {
  // console.log(video.currentTime) 获得当前的视频时间
  // 把当前的时间存储到本地存储
  localStorage.setItem('currentTime', video.currentTime)
}, 1000))

// 打开页面触发事件,就从本地存储里面取出记录的时间, 赋值给  video.currentTime
video.addEventListener('loadeddata', () => {
  // console.log(111)
  video.currentTime = localStorage.getItem('currentTime') || 0
})