JavaScript高级:防抖和节流

1 防抖(debounce)

单位时间内,频繁触发事件,只执行最后一次

【例子】王者荣耀英雄回城,只要被打断就要重新来

【应用场景】1. 搜索框搜索输入。只需用户最后一次输入完,再发送请求;2. 手机号、邮箱验证输入检测。

【需求】鼠标在盒子上滑动,并在盒子上显示滑动的次数

如果不使用防抖, 那么在盒子上的数字将会增加的非常快,如果是一些非常消耗性能的代码,可能会造成卡顿

1.1 使用 lodash 库实现防抖

无论滑动多少下 1s后才加1

       语法:

        _.debounce(func, [wait=0], [options={}])

        func: 需要防抖的函数

        wait: 延迟执行的时间

        options: 配置对象

【代码】

const box = document.querySelector('.box')
let i = 1
function mouseMove() {
    // 如果里面存在大量消耗性能的代码,比如dom操作,比如数据处理,可能造成卡顿
    box.innerHTML = i++
}
box.addEventListener('mousemove', _.debounce(mouseMove, 1000))

1.2 手写防抖函数

【代码】

        // 2.手写防抖函数
        // 核心是利用 setTimeOut 定时器实现
        // 2.1 声明定时器变量
        // 2.2 每次鼠标移动(事件触发)的时候先判断是否有定时器,如果有则清除以前的定时器
        // 2.3 如果没有定时器,则开启定时器,存入定时器变量里面
        // 2.4 在定时器里面写函数调用


        function debounce(fn, t) {
            let timer = null
            return function () {
                if (timer) clearTimeout(timer)
                timer = setTimeout(function () {
                    fn()
                }, t)
            }
        }

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

2 节流(throttle)

 单位时间内,频繁触发事件,只执行一次

【例子】王者荣耀英雄技能,在那段时间内你只能用一次该技能,下次想要用,需要等待技能冷却完毕

【应用场景】1. 鼠标连续触发某事件(如鼠标连续点击),只在单位时间内执行一次; 2. 监听滚动事件scroll,每隔100ms执行一次,实现防抖效果;3.页面尺寸缩放 resize

2.1 使用lodash库实现节流

        语法:

        _.throttle(func, [wait=0], [options={}])

        func: 需要节流的事件处理函数

        wait: 在wait 秒内最多执行func 一次的函数

box.addEventListener('mousemove', _.throttle(mouseMove, 3000))

2.2 手写节流函数

        // 2.2 手写节流函数
        // 核心是利用 setTimeOut 定时器实现
        // 2.2.1 声明定时器变量
        // 2.2.2 每次鼠标移动(事件触发)的时候先判断是否有定时器,如果有则清除以前的定时器
        // 2.2.3 如果没有定时器,则开启定时器,存入定时器变量里面
        // 2.2.4 在定时器里面写函数调用
        function throttle(fn, t) {
            let timer = null
            return function () {
                if (timer) return
                timer = setTimeout(function () {
                    fn()
                    timer = null
                }, t)
            }
        }
        box.addEventListener('mousemove', throttle(mouseMove, 3000))

因为在 setTimeout 中是无法删除定时器的,因为定时器还在运作,所以使用timer = null 

3 节流案例

【需求】在一个网页中播放了一个视频,在我下次再次打开这个页面时,视频的进度在我之前播放到的位置

【补充知识】

【代码】 

  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
  <script>
    // ontimeupdate  触发频次太高,我们设定 1秒钟触发一次
    const video = document.querySelector('.video video')
    video.ontimeupdate = _.throttle(() => {
      // console.log(video.currentTime)
      // 把间隔一秒就把当前播放时间存储到本地存储中
      localStorage.setItem('currentTime', video.currentTime)
    }, 1000)


    // 打开页面的时候,从本地存储中获取当前播放时间
    video.onloadeddata = () => {
      video.currentTime = localStorage.getItem('currentTime') || 0
    }


  </script>

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
防抖节流是优化 JavaScript 代码性能的两个重要技术,它们可以控制函数的执行频率,从而提高代码的响应速度和性能。下面是用 JavaScript 实现防抖节流的示例代码: ## 防抖 防抖可以控制一个函数在一段时间内只执行一次,常用于输入框搜索、滚动加载等场景。以下是一个基本的防抖函数实现: ```javascript function debounce(func, delay) { let timerId; return function(...args) { if (timerId) { clearTimeout(timerId); } timerId = setTimeout(() => { func.apply(this, args); timerId = null; }, delay); }; } ``` 这个函数接收两个参数,第一个参数是要进行防抖处理的函数,第二个参数是等待时间。该函数返回一个新的函数,每次调用这个新的函数时,会启动一个计时器,等待指定的时间后才会执行传入的函数。 例如,假设我们有一个搜索函数 search(),需要防抖处理,等待 500 毫秒后执行。可以这样调用: ```javascript const debouncedSearch = debounce(search, 500); input.addEventListener('input', event => { debouncedSearch(event.target.value); }); ``` 上面的代码将输入框的输入事件绑定到 debouncedSearch 函数上,每次输入事件发生时,debouncedSearch 函数会启动一个计时器,等待 500 毫秒后才会调用 search 函数。如果在 500 毫秒内再次输入事件发生,计时器会被重置,等待时间重新开始计算。 ## 节流 节流可以控制一个函数在一段时间内最多执行一次,常用于滚动事件、resize 事件等场景。以下是一个基本的节流函数实现: ```javascript function throttle(func, delay) { let timerId; return function(...args) { if (timerId) { return; } timerId = setTimeout(() => { func.apply(this, args); timerId = null; }, delay); }; } ``` 这个函数接收两个参数,第一个参数是要进行节流处理的函数,第二个参数是等待时间。该函数返回一个新的函数,每次调用这个新的函数时,会启动一个计时器,如果计时器已经启动,就直接返回,否则会等待指定的时间后才会执行传入的函数。 例如,假设我们有一个图片懒加载函数 lazyLoad(),需要节流处理,等待 200 毫秒后执行。可以这样调用: ```javascript const throttledLazyLoad = throttle(lazyLoad, 200); window.addEventListener('scroll', throttledLazyLoad); ``` 上面的代码将滚动事件绑定到 throttledLazyLoad 函数上,每次滚动事件发生时,throttledLazyLoad 函数会启动一个计时器,等待 200 毫秒后才会调
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是小蟹呀^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值