一、函数防抖
函数防抖:当重复触发某一个行为(事件时),只执行最后一次触发。
1.为什么要函数防抖
某些情况下,浏览器的一些高频事件对于用户来说其实并没有太大必要,比如mousemove,scroll,resize。这种时候,我们可以将多次的重复触发,改成只执行最后一次,以此来提升执行速度,节省资源
2.如何实现防抖
实现原理:配合setTimeout
。提前定义变量用来保存setTimeout
的返回值,在每次重复触发事件,准备开启新的setTimeout
之前,先clearTimeout
上次的返回值,保证同一时间只有一个setTimeout
存在。
var t = null;
Dom.onmousemove = function (){
clearTimeout(t);
t = setTimeout(() => {
console.log("函数防抖:多次触发只会执行一次");
}, 300);
}
3.函数防抖应用场景
一些高频事件,在被连续触发时,其实只需要生效一次即可,如:
- 搜索框搜索输入:只需用户最后一次输入完,再发送请求
- 以此可以延伸出手机号、邮箱等输入时的实时验证
- 窗口大小事件onresize,只需窗口调整完成后,计算窗口大小,防止重复渲染
二、函数节流
函数节流:不管事件的触发频率有多高,只会间隔设定的时间执行一次目标函数。简单来说:每隔单位时间,只执行一次
1.为什么要函数节流
某些情况下,浏览器的一些高频事件对于用户来说其实并没有太大必要,比如懒加载中的scroll事件。但是如果使用函数防抖的话,只有用户停止滚动后,才会判断是否到了页面底部;如果使用函数节流,只要页面滚动就会间隔一段时间判断一次,即保留了用户体验,又提升了执行速度,节省资源。
2.如何实现函数节流
let time = null;
Dom.onmousemove = function (){
if (time) return;
time = setTimeout(() => {
console.log('函数节流');
time = null;
}, 300);
}
3.函数节流使用场景
一些高频事件,在被连续触发时,需要限定在单位时间内只执行一次,如:
DOM 元素的拖拽(mousemove)
Canvas 模拟画板功能(mousemove)
Input输入框单位时间内搜索功能
懒加载,在滚动过程中判断是否需要加载图片(scroll)
页面滚动到底部加载更多(scroll)等
三、防抖节流函数封装
// 防抖
debounce(fn: any, delay: any) {
// 定时器
let timer: any = null
// 将debounce处理结果当作函数返回
return () => {
// 保留调用时的this上下文
let context = this
// 保留调用时传入的参数
let args = arguments
// 每次事件被触发时,都去清除之前的旧定时器,这里是闭包,timer变量必须清除
if (timer) {
clearTimeout(timer)
}
// 设立新定时器
timer = setTimeout(function () {
fn.apply(context, args)
}, delay)
}
},
// 节流
throttle(fn: any, gapTime: any) {
if (gapTime == null || gapTime == undefined) {
gapTime = 2000 //时间间隔默认为2秒
}
let _lastTime: any = null
// 返回新的函数
return () => {
let _nowTime = +new Date()
if (_nowTime - _lastTime > gapTime || !_lastTime) {
fn.apply(this, arguments) //将this和参数传给原函数
_lastTime = _nowTime
}
}
},