函数防抖和节流

在前端开发过程中,经常遇到一些持续触发的事件,如 resize、scroll、mousemove、键盘事件等,但有些时候不希望这类事件持续触发。

因此,防抖和节流就是解决这类需求应运而生的。

以键盘事件为例,一般除非要求输入模糊匹配时,要求实时获得输入框的值(见案例:https://www.cnblogs.com/danew/p/11530402.html);

但平时输入框带验证时,你会经常遇到刚打一个字就提示输入格式不正确,红色的提醒很醒目,但是也逼死强迫症,我刚输入邮箱的第一位就弹我?难道我邮箱都填不对?就不能等我填完再提醒是否正确?   (素质三连...)

其判断原理是每次键盘事件都获取value并执行一次校验,所以及时是及时了(比较占用性能),但用户体验不太好,有时候不需要这么及时,上代码简单分析一下这类事件的原理:

<div id="wrap">
    <input id="key" type="text">
    <p id="content"></p>
  </div>
    
  <script>
        let key = document.getElementById('key');
        let content = document.getElementById('content');

        key.onkeyup=show;

        function show() {
            content.innerHTML+=this.value+'<br/>';       // 每次触发事件,都获取一次 value 值
        }
  </script>

然后是效果图!(最喜欢贴图了,排版好看点...)

 

那怎么用防抖改良这个代码呢?其实,防抖的效果就是让你在输入的时候,不执行下一步,等你输入完成后,在键盘被释放了一小段的间隔后,执行下一步操作(比如执行校验)。

 <div id="wrap">
    <input id="key" type="text">
    <p id="content"></p>
  </div>
    
  <script>
        let key = document.getElementById('key');
        let content = document.getElementById('content');

        key.onkeyup=debounce(show,1000);

        function show() {
            content.innerHTML+=this.value+'<br/>';
        }
        //我叫函数防抖
        function debounce(func,delay) {
            let timer = null;

            return function () {
                let context = this;     //必须保存事件的this
                let args = arguments;   //参数也要保存
                if(timer){
                    clearTimeout(timer);  //事件再次触发时,那就取消之前的定时事件
                }
                timer = setTimeout(()=>{
                    func.call(context,...args);     // 其实用的比较多的是apply,直接传参数组
                    // 这里我就用call,据说call的性能比apply要好点(有大佬测试过),特别是参数大于3个的时候,如果参数<=3,两个五五开
                },delay)
            }
        }
</script>

好了,上效果图!

 

输入邮箱还不是很快的么,这里只有等键盘释放超过1s,才能执行对应的绑定事件(可以执行校验,此处省略),如果释放时间未到,则会取消上一次的定时器,重新计时。

所以事件防抖有点像打游戏,释放大招需要1s,但你可以通过按其他的键或是走位,重置读秒,取消大招,防止误伤队友或是空放技能;也可以一直按着按键不放(不断重置cd),等瞄准了再松开,然后放出大招。

那有人问了:我想走A怎么办?或者站撸一直普A行不行?那就请看看节流!

节流与防抖不同,当你一直按着按键时,节流会定时执行一次绑定事件。就是说,你装备比较好,可以对着BOSS站撸,一直按着F键,攻击会定时触发,然后全程只需按着F键,就能杀死BOSS!

上代码!

<div id="wrap">
    <input id="key" type="text">
    <p id="content"></p>
</div>
    
<script>
        let key = document.getElementById('key');
        let content = document.getElementById('content');

        key.onkeypress=throttle(show,1000);  //注意,这里 keypress 事件才支持一直按

        function show() {
            content.innerHTML+="我普A了BOSS一次!"+'<br/>';
        }

       // 我叫节流,能定时攻击你的那个 
        function throttle(func,delay) {
            let timer = null;
            return function () {
                const context = this;  //保存事件的触发对象
                let args = arguments;
                if(!timer){            //必须确保上一次定时器执行完毕
                    timer = setTimeout(()=>{
                        func.call(context,...args);
                        timer=null;    //及时清理,表示执行完毕,     clearTimeout后timer仍有值!!!这里有坑!画重点!!!
                    },delay)
                }
            }
        }
</script>

好了,上效果图!

 

 

总结:

防抖:触发事件后必须等待一个delay才能执行,频繁触发只会重置等待时间。打游戏可以通过连续按键用来重置技能读秒,或延迟释放技能。

节流:允许你频繁触发事件,但我只会按我的节奏(delay周期)来执行事件。打游戏一直按着按键一直普A,可以省得频繁操作按键懒人打法,人民币玩家打法

 

 

转载于:https://www.cnblogs.com/danew/p/11530310.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值