为什么需要防抖和节流?
- 不知大家是否有过这样的经历,当我们使用滚轮,虽然你只是滚动了一次,但后台却调用了scroll方法好多次,如下图
window.addEventListener('scroll',()=>{console.log('a')})
- 那如果我们需要对页面精确的滚动距离进行一些操作的时候,就会出现问题,,当然除了滚动还有其他的事件也有此类问题,由此防抖和节流方法应运而生
防抖
- 触发事件的数秒内,函数只能执行一次,如果在规定时间内再次触发,那么时间重新计算
立即执行
- 字面上的意思,在事件触发后立即执行函数,但根据防抖的原理,执行函数后的一定时间内,如果再次触发事件则重置时间
window.addEventListener("scroll", scrolling());
function scrolling() {
let timeout = null;
return function() {
if(timeout) clearTimeout(timeout);
let constTime = !timeout; //存储此时timeout的状态
timeout = setTimeout(() => {
timeout = null;
}, 1000);
if(constTime) console.log("防抖---立即执行");//对事件的操作放置此处,若需新创建函数,则需.call()等方法绑定
};
}
非立即执行
- 函数会在事件触发一段时间后再执行,如果在时间内再次触发事件,时间将被重置
window.addEventListener("scroll", scrolling(example));
function scrolling(fn) {
let timeout = null;
return function() {
if(timeout)clearTimeout(timeout);
timeout = setTimeout(() => {
fn.call(this); //对事件的操作放置此处,第二种写法
}, 1000);
};
}
function example(){
console.log("防抖---非立即执行");
}
疑惑点
问:为什么需要返回一个函数?
答:因为要让函数形成闭包,从而延长settimeout函数的生命周期,不然函数每执行一次,变量timeout都会被重新覆盖
问:立即执行和非立即执行的区别
答:settimeout函数本身的作用就是延时执行,所以非立即执行函数很好理解。而立即执行函数利用的就是settimeout的返回值可以证明其所在的状态
节流
- 不停的触发事件,在一定时间内,函数只会调用一次
时间戳
window.addEventListener("scroll", scrolling());
function scrolling() {
let time = null;
return function() {
let now = Date.now();
if(now - time > 1000){
console.log('a');
time = now;
}
};
}
定时器
window.addEventListener("scroll", scrolling());
function scrolling() {
let time = null;
return function() {
let now = Date.now();
if(now - time > 1000){
console.log('时间戳');
time = now;
}
};
}
借鉴:网络上各种文章 + 自己理解
如有错误,希望提出
希望大家都能早日拿到心仪的offer,加油,共勉