今天看了掘金的文章函数的防抖和节流,然后想自己总结一篇,应证一下是否学会了。

先来 一个 普通情况下的截图

normal

防抖

含义:一个函数如果在一段时间内不断触发,那么我们就让这个事件在停止触发一段时间后发生,如果在这个时间内重新触发了那么这个时间重新开始计算。
案例: 搜索框联想搜索时,浏览器窗口 resize 事件、Scroll 事件等。

debounce

debounce.js
  • js
  • js
1
2
3
4
5
6
7
8
9
10
11
12
//函数的防抖
function debounce(fun, delay){
let timer;
return function(args){
let that = this,
_args = args;
clearTimeout(timer);
timer = setTimeout(function(){
fun.call(that, _args);
}, delay)
}
}

节流

含义: 规定函数在一定的时间段内执行一次,如果在这个时段内多次触发,也只会触发一次。

throttle

throttle.js
  • js
  • js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 节流函数
function throttle(fun, delay){
let last = +new Date(), timer;
return function(args){
let that = this,
_args = args,
now = +new Date();
if(last && (now - last > delay)){
last = now;
clearTimeout(timer);
timer = setTimeout(function(){
fun.call(that, _args);
}, delay)
}
}
}

注意: 在防抖和节流函数中,在闭包函数内留住 this 还是选择 闭包外留住 this,最后函数中 this 的指向不一样。闭包外留住 this 指向的是 外层函数所指的 this,闭包内留住的 this 指向的是 接受外层函数返回函数的 变量 所指的 this

test.js
  • js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(function(){
class lazy {
constructor(selector){
this.lazyImg = document.querySelectorAll(selector);
this.init();
}
init(){
window.scrollFun = this.throttle(this.judge, 200);
window.addEventListener('scroll', window.scrollFun);
}
judge(){
console.log(this);
}
throttle(fn, delay){
// 节流 每隔一段时后 触发一次函数
let timer,
that = this, // 这里留住 this 指向的是 throttle的 this(lazy)
start = +new Date();
return function(args){
let _args = args,
//that = this, // 这里留住 this 指向的是 scrollFun 的 this(window)
now = +new Date();
if(now - start > delay){
start = now;
clearTimeout(timer);
timer = setTimeout(function(){
fn.call(that, _args);
}, delay);
}
}
}
}
new lazy('article img');
})();