防抖
- 在滚动事件,鼠标划过事件做复杂计算或者实现一个按钮的防二次点击操作都需要用到函数防抖,特别是前者,易产生页面卡顿
- 防抖和节流都是防止函数多次调用的,区别在于,假设一个用户一直触发这个函数,每次触发函数的间隔小于wait,防抖的情况下只会调用一次,而节流的情况会每隔一定时间(参数wait)调用函数
节流
防抖和节流在本质上是不一样的。防抖动是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行
// func是用户传入需要防抖的函数
// wait是等待时间
const debounce = (func, wait = 50) => {
// 缓存一个定时器id
let timer = 0
// 这里返回的函数是每次用户实际调用的防抖函数
// 如果已经设定过定时器了就清空上一次的定时器
// 开始一个新的定时器,延迟执行用户传入的方法
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, wait)
}
}
// 不难看出如果用户调用该函数的间隔小于wait的情况下,上一次的时间还未到就被清除了,并不会执行函数
封装防抖
function debounce(fn, delay) { //闭包 防抖的函数
let timer = null;
return function() { //arguments存在函数内部
clearInterval(timer);
timer = setTimeout(() => { //箭头函数解决arguments问题。箭头函数没有arguments
fn.apply(this, arguments); //arguments表示return后面的函数。但是此函数可能需要传递多个参数
}, delay);
}
}
封装节流
function throttle(fn, delay) {
let startTime = 0; //初始时间
return function() {
let currentTime = new Date().getTime(); //获取当前时间的毫秒数 1970.1.1离当前时间的毫秒数
console.log(currentTime - startTime);
if (currentTime - startTime > delay) { //第一次的事件时间和第二次事件的时间>2000,触发事件
fn.apply(this, arguments); //触发事件
startTime = currentTime; //当前的时间赋值给上一次的时间
}
}
}