防抖函数(debounce)
定义:当持续触发事件,一定时间内没有触发事件,事件处理函数才会执行一次,如果在设定的时间到来之前,又一次触发了事件,就重新开始计时。
案列
我们通过一个简单案例来一步步实现,当我们在输入框时,我们需要在控制台打印输入的值,这个需求很简单:
let input =document.querySelector('input')
input.addEventListener("keyup",function (e) {
console.log(e.target.value);
})
执行后我们发现,控制台会将我们每次输入的值都打印出来,然而实际上我们不需要如此高频的打印,此时我们需要输入完成,且不在输入,并且在1秒后将输入的值打印出来,首先我们来实现第一步,1秒后在打印结果,那么我们自然就想到了定时器
function debounce(delay,value) {
setTimeout(function() {
console.log(value);
}, delay);
}
input.addEventListener("keyup",function (e) {
debounce(1000,e.target.value)
})
然而执行完上述函数,我们发现该方法只是在延迟一秒后,将我们每次输入的值都打印了出来,这样完全不符合我们的预期,这时我们就想到,如果我们每次输入时,将上次的定时器清除不就好了,这样第二次输入时,第一次的值就不会被打印出来,所以我们可以这样写
function debounce(delay,value) {
let timer
clearTimeout(timer)
timer=setTimeout(function() {
console.log(value);
}, delay);
}
想到这里,我们就离成功不远了,执行后我们发现,结果还是和上次一样,这是为什么,是因为我们每次触发‘keyup’事件时都会执行一次函数,函数里的timer每次都是undefined,这样定时器自然就没被清除,如何解决呢,我们可以将timer变量储存在内存中,这样下次执行这个函数时,timer的值就不会为undefined,将局部变量储存在内存中,那么我们自然就想到了闭包
let input = document.querySelector('#input')
// 防抖函数
function debounce(delay) {
let timer
return function (value) {
cleanTimeout(timer)
timer = setTimeout(function () {
console.log(value);
}, delay);
}
}
let debounceFc = debounce(1000)
input.addEventListener("keyup", function (e) {
debounceFc( e.target.value)
})
这样一个基本的防抖函数就实现了
节流函数(throttle)
定义:当持续触发事件时,保证一段时间内,只调用一次事件处理函数,也就是一段时间只做一件事情
案例
场景:当我们多次点击按钮时,不论点击多少次,只希望在1秒内它只在控制台内打印一次 首先实现点击按钮,1秒后打印事件
let btn = document.querySelector('button')
function throttle() {
setTimeout(() => {
console.log('click');
}, 1000);
}
btn.onclick = throttle()
执行完发现结果是点击多少次打印多少次,那么我们如果给当前事件加入一个状态呢,只有当不是工作状态时,才执行函数
function throttle() {
let flag
if (!flag) {
flag=setTimeout(() => {
console.log('click');
}, 1000);
}
}
点击按钮发现效果和上次一样,原因是我们每点击一次,都会进入‘throttle’函数内,此时的flag都为‘false’,到了这里我们肯定想到了,将flag变量储存在内存中,只有满足条件时,才会执行,那么我们此时就可以用到了闭包 一个基本的节流函数就完成了
let btn = document.querySelector('button')
function throttle() {
let flag
return function () {
if (!flag) {
flag=setTimeout(() => {
console.log('click');
flag=null
}, 2000);
}
}
}
btn.onclick = throttle()