防抖

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始计时。

1
2
3
4
5
6
7
8
9
10
11
12
13
function debounce(fn,wait){
var timer = null
return function(){
timer && clearTimeout(timer) //一定时间段内重复触发,重新计时
timer = setTimeout(() => {
fn()
},wait)
}
}
function handle(){
console.log(Math.random())
}
window.addEventListener('scroll',debounce(handle,1000))

节流

当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function throttle(fn,delay) {
var timer = true
return function(){
if(!timer) return; //已经在计时了,不必重复操作
timer = false //计时开始
setTimeout(() =>{
fn()
timer = true //一次流程完成
},delay)
}
}
function handle(){
console.log(Math.random())
}
window.addEventListener('scroll',throttle(handle,1000))

防抖+节流

防抖有时候因为触发太过频繁,导致一次响应都没有,所以希望固定的时间必定给用户一个响应,于是就有了防抖 + 节流的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function throttle(fn, delay) {
let last = 0, timer = null;
return function (...args) {
let now = new Date();
//时间不到,防抖
if (now - last < delay){
clearTimeout(timer);
setTimeout(function() {
last = now;
fn.apply(this, args);
}, delay);
} else {
// 这个时候表示时间到了,必须给响应
last = now;
fn.apply(this, args);
}
}
}