函数防抖与函数节流

在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。

防抖(debounce)

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

节流(throttle)

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

一、防抖

先看下面一段代码。没加防抖前鼠标滑动一直触发mousemove事件,所以count一直再

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .num {
        width: 500px;
        height: 300px;
        border: 1px solid red;
        margin: 30px auto;
        font-size: 30px;
        font-weight: 800;
        text-align: center;
        line-height: 300px;
        background-color:#666666;
      }
    </style>
  </head>
  <body>
    <div class="num"></div>

    <script>
      //没加防抖
      var mynum = document.querySelector(".num");
      var count = 0;
      function addCount() {
        count++;
        mynum.innerHTML = count;
      }
      addCount();
    </script>
  </body>
</html>

没加防抖前鼠标滑动一直触发mousemove事件,所以count一直自加
在这里插入图片描述
增加防抖,就是加一个定时器。整段代码表示:鼠标触发mousemove事件,会隔1000毫秒后让count++。如果在1000毫秒内一直触发mousemove事件,则会清除上一次触发事件的定时器,开启一个新的定时器。整个效果就是触发事件的间隔在1000毫秒内的话是不会实现count++的,只有事件连续触发的间隔在1000毫秒以上才会实现一次count++

     var timer;
      mynum.onmousemove = function () {
        clearTimeout(timer);
        timer = setTimeout(function () {
          count++;
          mynum.innerHTML = count;
        }, 1000);
      };

上面这段代码还可以通过闭包的形式封装成一个防抖函数:

function debounce(fnc, wait) {
        var timer;
        return function () {
          clearTimeout(timer);
          timer = setTimeout(fnc, wait);
        };
      }
mynum.onmousemove = debounce(addCount,1000)

防抖效果图如下:
在这里插入图片描述

二、节流

规定:在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

方式一:用时间搓的方式实现节流

   function throttle(fnc,wait){
        var lastTime = Date.now()
        return function(){
            var nowTime = Date.now()
            if( (nowTime - lastTime) > wait ){
                lastTime = nowTime
                fnc()
            }
        }
    }
    mynum.onmousemove = throttle(addCount,1000)

方式二:用定时器的方式实现节流。

 function throttle(func,wait){
        var timer;
        return function(){
            if(!timer){
                timer = setTimeout(() => {
                console.log(timer)
                    timer = null
                    func()
                },wait)
            }
        }
    }
 mynum.onmousemove = throttle(addCount,1000)

计时器方式的解读:多次触发事件,会产生多个timer,而只有执行了func()才会count++。第一次触发事件会有一个timer,该timer要在wait事件后才会变成null,所以多次触发事件,只有当wait秒后的那个timer为空才会再次执行func(),其他timer都是有值的没法执行func()
在这里插入图片描述
节流实现的效果图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值