目录
- 防抖
- 节流
- 使用场景
一、防抖
手写-防抖
// 防抖
function debounce(fn, delay = 300) {
//默认300毫秒
let timer;
return function () {
const args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args); // 改变this指向为调用debounce所指的对象
}, delay);
};
}
window.addEventListener(
"scroll",
debounce(() => {
console.log(111);
}, 1000)
);
1)无参数版本
function debounce1(fn,wait=300){
let timer;
return ()=>{
if(timer){clearTimeout(timer)}
timer = setTimeout(()=>{
fn();
}, wait)
}
};
window.addEventListener(
"scroll",
debounce1(() => {
console.log(222);
}, 1000)
);
二、节流
1) 时间差版本
//定义:当持续触发事件时,保证隔间时间触发一次事件。
//1. 懒加载、滚动加载、加载更多或监听滚动条位置;
//2. 百度搜索框,搜索联想功能;
//3. 防止高频点击提交,防止表单重复提交;
function throttle(fn,wait){
let pre = 0;
return function(...args){
let now = Date.now();
if( now - pre >= wait){
fn.apply(this,args);
pre = now;
}
}
}
function handle(){
console.log(Math.random());
}
window.addEventListener("mousemove",throttle(handle,1000));
2) flag+定时器版本
// 节流
// 设置一个标志
function throttle(fn, delay) {
let flag = true;
return () => {
if (!flag) return;
flag = false;
timer = setTimeout(() => {
fn();
flag = true;
}, delay);
};
}
window.addEventListener(
"scroll",
throttle(() => {
console.log(111);
}, 1000)
);
三、使用场景
1)节流
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
2)防抖
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
函数防抖的应用场景
连续的事件,只需触发一次回调的场景有:
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测(change、input、blur、keyup等事件触发,每次键入都会触发)
- 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
- 鼠标的mousemove、mouseover
- 导航条上,用户不停的在导航区域滑动相当于
函数节流的应用场景
间隔一段时间执行一次回调的场景有:
- 滚动加载,加载更多或滚到底部监听,window.onscroll和滑到底部自动加载更多
- 谷歌搜索框,搜索联想功能
- 高频点击提交,表单重复提交
参考
总结
- 防抖和节流都是为了解决频繁触发某个事件的情况造成的性能消耗。
- 防抖就是在频繁触发一个事件后,冷静下来执行最后一次,例如:在进行搜索的时候,当用户停止输入后调用方法,节约请求资源
- 节流就是在频繁触发某个事件的情况下,每隔一段时间请求一次,类似打游戏的时候长按某个按键,动作是有规律的在间隔时间触发一次【一段时间内只执行一次,无论你怎么触发】
- 防抖:在事件触发n秒后执行函数,如果在n秒内再次出发,重新计时
- 节流:当多次执行某一动作,每个一段时间,只执行一次函数。