2021-07-15个人对防抖的理解!

个人对防抖的理解!


前言

防抖和节流是前端经常会被提起以及涉及到的内容,更是前端性能优化的手段之一,我初学防抖和节流也遭遇了很多坑,所以想写一篇博客一则当作学习笔记,二则如果能帮助别人学习我就非常开心了!


一、防抖是什么?

个人觉得要想搞懂防抖不应该把注意力集中在防抖两个字上,而应该从生活中的例子出发去认识防抖。比如有一台电视机,规定某个频道正常播放为正常响应执行事件触发函数,规定更换频道为触发事件,假设现在频繁更换频道但电视机只会播放你最后一次更改成的频道,这其实就是防抖,还有例如电梯门,当有很多人进出的时候如果没有时间间隔的去开关门,就会面临着多次门的开关,这样对于电梯寿命的损害特别大,在这个事件中我们把电梯关门看作是一次正常的响应执行事件触发函数,进出的人对应着事件触发源,电梯门只会在最后一个人出去或者进入后才会关闭,这其实也是防抖。可以看出来关键词为最后一个,所以我所理解的防抖就是通过设置与合理清除定时器忽略掉多次事件在一定时间间隔触发源所触发的事件而只去响应最后一次的触发源的触发和执行相应的事件处理函数的现象。

二、防抖的实现

1.定时器

 <button id="fd" type="button" onclick="FDfun(sayhello,4000)">防抖按钮</button>
    <script>
        let btn = document.querySelector("#fd")
        function sayhello(){//响应事件函数
            console.log("俺也一样")
        }
        function FDfun(fun,time,self){//防抖函数
            setTimeout(function() {
                fun()
            }, time);
             
        }
    </script>

首先我们肯定都能想到引入定时器去给检测事件的触发次数的感应有合理的检测时间,但是我们这样写 只能延缓事件的执行,并不能起到真真的防抖作用。

多次点击触发的执行结果

防抖的作用将多次点击忽略只响应最后有一次点击,这里我们可以想到清除定时,所以

<button id="fd" type="button" onclick="FDfun(sayhello,4000)">防抖按钮</button>
    <script>
        let btn = document.querySelector("#fd")
        function sayhello(){
            console.log("俺也一样")
        }
        function FDfun(fun,time,self){ 
            let tim
            if(tim){
                clearTimeout(tim)
            }
           tim=setTimeout(function() {
                fun()
            }, time);
            
        }
    </script>

 执行结果:

这里我们可以看出好像清除定时器并没有取得合理的结果,这是为什么了?

原因就在于多次事件的触发定义了多次接受定时器的tim变量,所以不通过的点击对应着不同的防抖定时器(即感应事件触发的时间长度)

 那怎么样让多个事件触发去对应同一个定时器变量了或者定时器了,在这里我们就可以想到作用域、作用域链和闭包

2.多个定时器访问同一变量(作用域链、闭包)

<button id="fd" type="button" onclick="FDfun(sayhello,4000)">防抖按钮</button>
    <script>
        let btn = document.querySelector("#fd")
        function sayhello(){
            console.log("俺也一样")
        }
        let tim
        function FDfun(fun,time){ 
                if(tim){
                clearTimeout(tim)
            }
             tim=setTimeout(function() {
                fun()
            }, time); 
            }
    </script>

多次点击执行结果

 我们可以看到事件只发生了一次!


 3.this的指向问题!

<button id="fd" type="button" onclick="FDfun(sayhello,4000)">防抖按钮</button>
    <script>
        let btn = document.querySelector("#fd")
        function sayhello(){
            console.log("俺也一样")
            console.log(this)
        }
        let tim
        function FDfun(fun,time){ 
                if(tim){
                clearTimeout(tim)
            }
             tim=setTimeout(function() {
                fun()
            }, time); 
            }
    </script>

执行结果:

 

 我们可以看到这里的this指向为window并不是button按钮,所以这里很不合理,我们需要改变this的指向。

用call方法改变this的指向:

 <button id="fd" type="button" onclick="FDfun(sayhello,4000)">防抖按钮</button>
    <script>
        let btn = document.querySelector("#fd")
        function sayhello(){
            console.log("俺也一样")
            console.log(this)
        }
        let tim
        function FDfun(fun,time){ 
                if(tim){
                clearTimeout(tim)
            }
             tim=setTimeout(function() {
                // fun()
                fun.call(this)
            }, time); 
            }
    </script>

执行结果:

我们可以看到结果以旧为window,这又是为什么了,原因就在于我能所绑定事件的方法是onclick() ,onclick绑定事件直接相当于在window中调用事件函数,所以其指向是window;

因此我们应该在绑定事件的时候应该把this作为参数传入

<button id="fd" type="button" onclick="FDfun(sayhello,4000,this)">防抖按钮</button>
    <script>
        let btn = document.querySelector("#fd")
        function sayhello(){
            console.log("俺也一样")
            console.log(this)
        }
        let tim
        function FDfun(fun,time,self){ 
                if(tim){
                clearTimeout(tim)
            }
             tim=setTimeout(function() {
                // fun()
                fun.call(self)
            }, time); 
            }
    </script>

执行结果:

三、总结

防抖是前端开发中所常用的提高性能的方式之一,防抖的实现涉及到了很多js中的关键知识,刚开始理解防抖不是很容易,所以在理解防抖之后就想写一篇文章来作为学习笔记,如果出现什么不对的地方欢迎大家的纠正,希望共同进步。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:在Vue项目中实现懒加载可以使用v-infinite-scroll插件。首先需要安装v-infinite-scroll插件,可以通过npm i v-infinite-scroll -D命令进行安装。然后在项目中引入lazyLoad,并使用Vue.use(lazyLoad)进行注册。\[1\] 引用\[2\]:v-infinite-scroll插件的使用方法是在需要实现懒加载的元素上添加v-infinite-scroll指令,并绑定一个事件load()。当滚动条距离页面底部300px时,load()事件会被触发。可以通过设置infinite-scroll-disabled属性来控制是否禁止触发加载。\[2\] 引用\[3\]:在el-table中实现滚动到底部加载更多数据可以使用v-infinite-scroll指令。将v-infinite-scroll指令添加到需要实现滚动的元素上,并绑定一个事件load()。当滚动到底部时,load()事件会被触发。\[3\] 问题: 如何实现v-infinite-scroll的效果? 回答: 要实现v-infinite-scroll的效果,可以使用lodash库中的debounce函数。首先,在Vue项目中引入lodash库。然后,在load()事件处理函数中使用debounce函数对实际的加载逻辑进行包装,设置一个适当的延迟时间。这样可以确保在滚动过程中只触发一次加载操作,避免频繁加载数据。 #### 引用[.reference_title] - *1* *2* [懒加载 , 滚动加载更多](https://blog.csdn.net/mushroomLNL/article/details/124177915)[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^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [element-ui的el-table表格实现无限滚动,使用自带的infinite-scroll](https://blog.csdn.net/qq_43437571/article/details/121864975)[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^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值