防抖与节流的封装函数与使用详解

防抖与节流

为什么使用防抖节流?
在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作、资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃。函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的。

防抖(debounce)

函数防抖就是在函数需要频繁触发情况时,只有足够空闲的时间,才执行一次。好像公交司机会等人都上车后才关门一样。他不会上来一个人就触发一次关门,而是等人陆续上来后等待一会再触发关门

场景:(当时间频繁触发后停止一段时间执行)

  • 实时搜索(keyup)
  • 拖拽( mousemove )
  • 手机号、邮箱验证输入检测
  • 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

我们以百度搜索框在输入完成后停顿一段时间便会进ajax请求为例子,我们实现输入框停止输入后再打印

//使用高阶函数,利用闭包封装
    <!-- <script src="../../plugin/helpers.js"></script> -->
   
        let oInp = document.getElementById('inp')
        let timer = null
        const debounce = (handler, delay) => {
            let timer = null //利用闭包保存同一个timer
            return () => {
                let _self = this //取debounce执行作用域的this
                let _arg = arguments //利用闭包保存参数数组
                clearTimeout(timer) //不断的执行函数不断的清除定时器
                timer = setTimeout(() => {
                    handler.apply(_self, _arg) //用apply指向调用debounce的对象,相当于_this.handler(args);
                }, delay)
            }
        }
        let shouValue = (e) => {
            console.log(e,this.value)
        }
        oInp.oninput = debounce(shouValue, 1000);

节流(throttle)

函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。好像水滴攒到一定重量才会落下一样。

场景: CON(不管时间触发的多么频繁,至少要每隔一段时间执行而不是等事件触发完了等一段时间执行)

窗口调整(resize)
页面滚动( scroll)
抢购疯狂点击( mousedown)

目前我有两种思路:

  • 使用定时器,定时一秒钟之后去执行,但是在这1s中不停的调用,不让他的定时器清零重新计时,不会影响当前的结果,还是那1s继续等,等1秒时触发(会出现停止操作还是会触发)
//保证一个时间段内执行一次
        const throttle = (handler, time) => {
            let timer
            return () => {
                if (timer) {
                    return //判断如果有计时器不清零直接返回啥也不做
                }
                let _self = this //取throttle 执行作用域的this
                let _arg = arguments //利用闭包保存参数数组
                timer = setTimeout(() => {
                    handle.apply(_self, _arg)
                    timer = null
                }, time)
            }
        }
        //触发事件
        window.onresize =  () => handle()
        //处理函数
        let test = () =>console.log("a")
        //调用throttle函数传参
        let handle = myPlugin.throttle(test, 2000)
  • 使用时间戳,先立即执行,只不过在下一次执行要等一段时间
 const throttle = (handler, time) => {
            let t 
            return () => {
                let _self = this //取throttle 执行作用域的this
                let _arg = arguments //利用闭包保存参数数组
                if (!t || Date.now() - t >= time ) {
                    handler.apply(_self , _arg );
                    t = Date.now(); //得到的当前时间戳
                }
            }
        }
        window.onresize =  () => handle()
        let test = () =>console.log("a")
        let handle = myPlugin.throttle(test, 2000)

判断两种方式差异,我们只需要判断是否需要立即执行,我们就可以把节流的两种合并在一起

//保证一段时间只执行一次
      constthrottle = (handler, time, immediately) => {
            if (immediately === undefined) {
                immediately = true //判断需要先立即执行
            }
            if (immediately) {
                let t
                return () => {
                    let _self = this //取throttle 执行作用域的this
                    let _arg = arguments //利用闭包保存参数数组
                    if (!t || Date.now() - t >= time) {
                        handler.apply(_self, _arg);
                        t = Date.now(); //得到的当前时间戳
                    }
                }
            }
            else {
                let timer
                return () => {
                    if (timer) {
                        return //判断如果有计时器不清零直接返回啥也不做
                    }
                    let _self = this //取throttle 执行作用域的this
                    let _arg = arguments //利用闭包保存参数数组
                    timer = setTimeout(() => {
                        handle.apply(_self, _arg)
                        timer = null
                    }, time)
                }
            }

        }
        window.onresize = () => handle()
        let test = () => console.log("a")
        let handle = myPlugin.throttle(test, 2000,true)
前端防抖节流使用场景很多。其中一种常见的场景是在用户输入搜索框时进行搜索提示。当用户快速输入时,如果每次输入都立即触发搜索请求,会造成过多的请求并降低性能。这时可以使用防抖来延迟执行搜索请求,只当用户停止输入一段时间后才触发搜索请求,避免不必要的请求。 另一个使用场景是在页面滚动时进行懒加载。当用户滚动页面时,如果每次滚动都立即加载图片或数据,会造成页面卡顿。通过使用节流,可以控制在一定时间内只触发一次加载,提高页面的流畅度。 此外,防抖节流还可以应用于按钮点击事件,防止用户频繁点击按钮导致重复提交或执行多次操作。通过设置适当的延迟时间,可以确保在用户点击按钮后只执行一次操作。 总之,前端防抖节流使用场景包括搜索提示、懒加载和按钮点击事件等,通过延迟执行或控制触发频率,可以提升用户体验和页面性能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [前端节流防抖的实景应用](https://blog.csdn.net/qq_52022825/article/details/125057737)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [防抖节流封装函数使用详解](https://download.csdn.net/download/weixin_38695061/14888196)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值