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))

JavaScript高级:防抖和节流_第1张图片

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

3 节流案例

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

【补充知识】

JavaScript高级:防抖和节流_第2张图片

【代码】 

  
  

你可能感兴趣的:(JavaScript,javascript)