javascript的防抖和节流

防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 在给DOM绑定事件时,有些事件我们是无法控制触发频率的。 如鼠标移动事件onmousemove, 滚动滚动条事件onscroll,窗口大小改变事件onresize,瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂,就会导致响应跟不上触发,出现页面卡顿,假死现象。 在实时检查输入时,如果我们绑定onkeyup事件发请求去服务端检查,用户输入过程中,事件的触发频率也会很高,会导致大量的请求发出,响应速度会大大跟不上触发。

针对此类快速连续触发和不可控的高频触发问题,debounce 和 throttling 给出了两种解决策略;
 

防抖:所谓防抖,就是指触发事件后在 n 秒后函数执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

节流:所谓节流,就是指连续触发事件但是在 n 秒中只能执行一次函数。节流会稀释函数的执行频率。

 

防抖和节流的区别:

防抖:在高频发的事件调用时,每次将定义好的定时器清除掉,只有当高频发事件调用最后一次的时候,由于没有再调用该事件函数,没有清除定义的定时器,那么定时器将正常工作,即定时器等待时间内连续调用10次后显示1,连续调用20次后显示的还是1。通俗来讲就是,你要我在30s内搬100块砖,我偷懒,我结束时才搬一块。

节流:在高频发的事件调用时,不会清除定义好的定时器。假设你的定时器为1s,加入if判断语句,如果你高频发事件的调用间隔小于1s,那么你在这1s的定时器等待时间内调用的次数都当成一次,即连续调用10次后如果花了三秒钟则显示3,连续调用20次后如果花了三秒钟那么也显示3,就是看你的调用时间。注意,将若干函数调用合成为一次(稀释函数的执行频率),并在给定时间过去之后,调用一次(仅仅只会调用一次)。通俗来讲就是,你要我在30s内搬100块砖,我搬,不过我每1s(定时器范围)才搬一块,多了我不干,所以我最后才搬了30块砖。

 

示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>javascript防抖和节流</title>
    <style>
        #content{
            height: 150px;
            line-height: 150px;
            text-align: center;
            font-size: 18px;
            color: white;
            background-color: gray;
        }
    </style>
</head>
<body>
    <div id="content" >0</div>
    <script>
        var content = document.getElementById('content');    
        var num = 1; 
        function count(){  //基础操作          
            content.innerHTML = num++;
        }

        // content.onmousemove = function(){//没有防抖节流
        //     count();
        // }

        //防抖
        function debounce(func, wait) {
            var timeout;//声明一个定时器
            return function () {

                if (timeout){//每次调用函数都先清除定时器
                    clearTimeout(timeout);
                } 
                
                timeout = setTimeout(function(){
                    func();//延迟调用函数
                }, wait);
            }
        }
        // content.onmousemove = debounce(count,500);
        
        //节流
        // 时间戳版的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候。
        function throttle1(func, wait) {//时间戳版
            var lastTime = 0;
            return function() {
                var currentTime = Date.now();
                if (currentTime - lastTime > wait) {//如果调用时间间隔大于定时器规定时间,执行函数
                    func();
                    lastTime = currentTime;//重置上一次函数被调用时的时间
                }
            }
        }
        // content.onmousemove = throttle1(count,1000);

        function throttle2(func, wait) {//定时器版
            var timeout;//定义定时器
            return function() {
                if (!timeout) {//如果未定义定时器
                    timeout = setTimeout(function(){
                        func();
                        timeout = null;//释放定时器                  
                    }, wait)
                }
            }
        }
        content.onmousemove = throttle2(count,1000);


    </script>
</body>
</html>

 

在Vue中使用防抖和节流函数


data(){
    return{
        debounceTimer:null //防抖定时器
        lastTime: 0 //用于节流函数计时器
    }

},

methods:{
    
    //防抖
    debounce(handle, wait) {
      var func = () => {
        if (debounceTimer) {
          //如果之前存在定时器,执行函数,清除定时器
          clearInterval(debounceTimer);
        }
        debounceTimer = setTimeout(()=>{ handle();},wait) //执行定时器包裹的 具体 函数
      };
      return func;
    },

    //节流
    throttle(handle, wait) {
      var func = () => {
        var currentTime = Date.now();
        if (currentTime - this.lastTime > wait) {
          //如果调用时间间隔大于定时器规定时间,执行函数
          handle(); //执行 具体 函数
          this.lastTime = currentTime; //重置上一次函数被调用时的时间
        }
      };
      return func;
    },

}

 

 

 

参考链接:https://www.jianshu.com/p/c8b86b09daf0

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值