防抖
言简意赅:函数的执行者冷静下来后(不一直抖动后),才真正执行。
深入理解:触发事件时,只在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新事件触发的时间为准,n 秒后才执行。比如频繁触发的某一函数,防抖可以只在最后一次触发后执行。总之,就是要等你触发完事件的 n 秒内不再触发事件,才执行。
// func是用户传入需要防抖的函数
// wait是等待时间
const debounce = (func, wait = 50) => {
// 缓存一个定时器id
let timer = 0
// 这里返回的函数是每次用户实际调用的防抖函数
// 如果已经设定过定时器了就清空上一次的定时器
// 开始一个新的定时器,延迟执行用户传入的方法
return function() {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func();
}, wait)
}
}
亦或是
<script>
...
function debounce(func,wait){
var timer;
return function(){
clearTimeout(timer);
timer = setTimeout(func,wait)
}
}
container.onmousemove = debounce(getUserAction,1000);
</script>
节流
在一定时间内,持续触发时间,事件只会在设定的时间内触发一次。
深入理解: 开闸放水。我想让你1s只流出多少水你就只能流多少水,多的水只能等到下个周期才能流出。
使用时间戳
当触发事件的时候,我们取出当前的时间戳,然后减去之前的时间戳(最一开始值设为 0 ),如果大于设置的时间周期,就执行函数,然后更新时间戳为当前的时间戳,如果小于,就不执行。
// func是用户传入需要防抖的函数
// wait是等待时间
const throttle = (func, wait = 50) => {
// 上一次执行该函数的时间
let lastTime = 0;
return function() {
// 当前时间
let now = +new Date()
// 将当前时间和上一次执行函数时间对比
// 如果差值大于设置的等待时间就执行函数
if (now - lastTime > wait) {
lastTime = now
func()
}
}
}
setInterval(
throttle(() => {
console.log(1)
}, 500),
1
);
亦或是
// 时间戳
function throttle(func, wait) {
var context, args;
var old = 0;
return function() {
var now = +new Date();
context = this;
args = arguments;
if (now - old > wait) {
func.apply(context, args);
old = now;
}
}
}