一、函数节流

一个函数执行一次后,只有大于设定的执行周期后才会执行第二次

原理:用时间戳来判断是否已到回调该执行时间,记录上次执行的时间戳,然后每次触发 scroll 事件执行回调,回调中判断当前时间戳距离上次执行时间戳的间隔是否已经到达 规定时间段,如果是,则执行,并更新上次执行的时间戳,这样循环下去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 节流函数
* @param fn 事件触发的操作
* @param mustDelay 间隔多少毫秒需要触发一次事件
*/
function throttle(fn,mustDelay){
let timer,
start = 0;
return function (){
let now = new Date().getTime(),
self = this,
args = arguments;
if(now > start + mustDelay){
fn.apply(self,args)
start = now;
}
}
}
window.onscroll =throttle(function(){
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log(scrollTop)
},200)

应用场景:

  1. 滚动加载,加载更多或者滚到底部监听
  2. 频繁点击按钮

函数防抖

一个需要频繁触发的函数,在规定时间内,只让最后一次执行,前面的不执行

原理:第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器,然后延迟一定时间再执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
*防抖函数
*@param fn 事件触发的操作
*@param delay 多少毫秒内连续触发事件,不会执行
*@returns {Function}
*/
function debounce(fn,delay){
let timer = null;
return function(){
let self = this,
args = arguments;
timer && clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(self,args);
},delay);
}
}
window.onscroll = debounce(function(){
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log(scrollTop)
},200)

应用场景

  1. 在input框中输入搜索内容的时候,浏览器不会马上就去执行
  2. 手机号、邮箱输入验证
  3. 窗口大小resize,只需要调整完成后,计算窗口大小,防止重复渲染