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滚动条;