防抖和节流原理及代码

1.防抖

1.1 描述:

在前端页面开发过程中,防抖是为了减少用户不必要的操作的一种优化手段,比如当点击一个按钮的时候,用户已经发起了请求,此时还没收到响应,但是用户以为还没有发送请求,因此频繁点击,导致多次触发请求,这样会导致用户体验变差,而多次发起请求操作也会造成网络资源的浪费。因此提出防抖,它的作用是在固定时间t(这个时间我们可以自己设置)内,多次触发请求只会按最后一次来计算,也就是说,用户点击一次按钮后,在t时间段内,用户如果又多次点击按钮的话,每一次重复点击,防抖函数都会把上次点击发起的计时给清理掉,从0开始计时,只有在0~t内没有再点击,事件才会被触发,其核心原理是通过定时器+闭包来实现。建议看看代码,只有看代码才能深刻理解其含义。

1.2 代码+原理

html里有一个按钮

<div id="button" > 这是一个按钮</div>
//选中这个元素
const button=document.querySelector("#button");
//给这个按钮绑定一个监听事件handleClick,同时对这个点击事件进行防抖处理,事件是200ms。
button.addEventListener("click",debounce(handleClick,200))//200是我们自己设置的时间,
function handleClick(){
    console.log("调试语句")
}
//防抖函数接收两个参数,fn指的是要触发的事件,delay指的是设定的时间t
function debounce(fn, delay) {
  let time=null;//设置一个时间标识让它等于null;
  return function() {
    if(time!=null){
    //每次触发判断时间是否等于null,如果是第一次触发那么time肯定等于null,如果在t内连续触发的话time就不等于null,此时说明有连续触发,因此将定时器清空;
        clearTimeout(time)
    }
    //再重新开始计时delay时长,如果在delay时长内都没有再点击的话,delay时间一过,就会触发handleClick事件。
    //这里使用闭包实现,是利用了闭包会保存变量,使其内存不被js垃圾回收机制清理掉的特点,不清楚的小伙伴可以详细了解下闭包原理
    time=setTimeout(()=>{//如果是第一次触发,那么当t时间过去后,就执行传过来的要触发的事件函数。
        fn();
    },delay)
  };
}

1.3应用场景

input输入;多次点击按钮触发请求;window窗口的resize

2.节流

2.1 描述:

节流与防抖相似,都是为了减少用户频繁触发事件的优化手段,不过节流的效果是如果用户频繁点击按钮,在一定时间内,多次点击只触发一次事件。举个例子,如果时间间隔我们都设置为1s,那么如果1~3s内我们都在频繁点击按钮,在防抖情况下,事件将会在3s后的最后一次点击延后1s后触发(仅触发一次),在节流情况下,事件将会在第2s的时候被触发一次,在第3s被触发一次,在第4s被触发一次;如果不理解请看源码及注释。将防抖和节流对比学习。

2.2 代码+原理

其实现原理是:计算上次触发与本次触发的时间查,将这个时间差设置为定时器的时间参数,从而保证每隔固定时间内都会触发一次。

<div id="button">这是一个按钮</div>
const button=document.querySelector("#button");
button.addEventListener("click",throttle(handleClick,2000));
function handleClick(){
    console.log("调试成功")
}
function throttle(fn, wait = 0) {
  let timerId;
  let lastInvoke = Number.MIN_SAFE_INTEGER; // 上次调用时间
  return function(...args) {
    // 当前时间
    const currTime = new Date().getTime();
    // 距离下次执行的剩余时间,如果这个剩余时间比0大的话就延迟,比0小的话就将延迟时间设为0;
    const remain = Math.max(lastInvoke + wait - currTime, 0);
    // 每次触发会清除上次的定时器,并将重新计算的剩余时间更新在setTimeout函数里。
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      lastInvoke = new Date().getTime();//将更新时间变成本次点击时间;
      fn(...args);//在remain时间后执行fn
    }, remain);
  }
}

2.3应用场景

scroll滚动条;

如有错误,欢迎指出,本人将持续记录、分享前端干货!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值