一、函数防抖
(一)防抖的理解
防抖就是将所有的触发都取消,在规定的时间结束过后才会执行最后一次,也就是说连续快速的触发只会执行最后一次结果。
也可以理解为游戏里的回城按钮,每点一下就会重新刷新回城进度,永远以最后一次点击为准。
例如:我们现在有一个输入框,在没有使用防抖的情况下,我们输入一个字符就会给服务器发送一次请求。
但是我们使用防抖过后,我们只会发送最后一次输入事件触发的请求。
(二)使用JS实现防抖
防抖可以使用定时器+闭包实现
关于闭包可以看这个MDN上的教程:
闭包 - JavaScript | MDN (mozilla.org)
防抖其本质就是用户每执行一次输入操作就开启一个定时器,如果用户继续输入,就把前面的定时器全部清除,永远只留下最后一个定时器。
const ipt = document.querySelector("input");
// 触发输入框输入事件
ipt.addEventListener('input', debounce(() => {
console.log("向服务器发送一次请求,内容为" + ipt.value);
}, 1000));
// 防抖函数,接收两个参数
// 一个是事件回调函数,一个是指定最后一次触发时间
function debounce(fn, delay) {
// 定时器,使用闭包将它缓存在内存中
let t = null;
return function () {
// 如果这次输入的时候检测到已经开启了定时器,就清除上一个定时器
if (t !== null) {
clearTimeout(t);
}
// 重新开启新的定时器,该定时器永远是最后一个定时器
t = setTimeout(() => {
// 等到定时器结束触发事件回调函数
fn();
}, delay)
}
}
(三)使用Lodash实现防抖
首先需要下载和引入lodash,下面是下载Lodash的官方网址:
Lodash 简介 | Lodash中文文档 | Lodash中文网 (lodashjs.com)
这一条讲的是防抖函数的使用:
lodash.debounce | Lodash中文文档 | Lodash中文网 (lodashjs.com)
_.debounce(回调函数, 延迟时间)
const ipt = document.querySelector("input");
ipt.addEventListener('input', _.debounce(() => {
console.log("向服务器发送请求,请求数据为:" + ipt.value);
}));
二、函数节流
(一)节流的理解
节流就是在规定的时间间隔内不会重复触发回调,只有过了这个时间间隔后才能触发回调,使用这种方法把触发频率变为少量触发。
可以理解为我们平时输入手机号获取验证码,获取验证码过后,用户在短时间内不能再获取验证码,只有等这个时间过了才能再次发送验证码。
(二)使用JS实现节流
节流也是使用定时器+闭包来实现
其本质就是使用一个变量来记录当前状态,如果我们在触发事件的时候这个变量状态是可以触发,就开启一个定时器后变为不可触发,等待定时器结束后再把状态改为可以触发。
let num = 0;
const span = document.querySelector("span");
const button = document.querySelector("button");
// 触发点击按钮num+1事件
button.addEventListener("click", throttle(() => {
num++;
span.innerText = num;
}, 2000))
// 节流函数,接收两个参数
// 一个是事件回调函数,一个是指定触发事件的间隔时间
function throttle(fn, delay) {
// 记录当前事件状态,true为可以触发,false为不可触发
let t = true;
return function () {
// 如果这次事件可以触发,就执行回调函数并开启一个定时器,然后将状态变为false
// 如果点击的时候事件不可触发,则状态一直为false
if (t) {
fn();
setTimeout(() => {
// 等到定时器结束触发事件回调函数,并重新把状态调为true
t = true;
}, delay)
}
t = false;
}
}
(三)使用Lodash实现节流
Lodash官方文档中节流函数的使用:
lodash.throttle | Lodash中文文档 | Lodash中文网 (lodashjs.com)
_.throttle(回调函数, 时间间隔)
let num = 0;
const span = document.querySelector("span");
const button = document.querySelector("button");
button.addEventListener("click", _.throttle(() => {
num++;
span.innerText = num;
}, 2000))