防抖
多次触发,最后一次 n 秒后执行
使用场景
- 登陆、发短信避免用户点击太快,以至于发送了多次请求
- 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多
- 文本编辑器实时保存
- 表单验证:在表单输入过程中,每次用户输入都可能触发验证操作。使用防抖函数可以延迟触发验证操作,只在用户输入完毕一段时间后进行验证,避免频繁的验证操作。
- 上拉下滑监听
- 搜索框实时搜索:当用户在搜索框中输入内容时,通常需要实时进行搜索。使用防抖函数可以延迟搜索请求的发送,只在用户停止输入一段时间后才真正发送请求,避免频繁的请求操作。
- 鼠标移动事件:在一些特定的交互场景中,需要根据鼠标的移动位置做出相应的交互。使用防抖函数可以延迟鼠标移动事件的触发,只在用户停止移鼠标一段时间后才执行相应的操作,避免过度频繁的操作。
实现
function debounce(fn, wait, immediate = false) {
let timer = 0;
let isInvoke = false;
return function (...args) {
if (timer) clearTimeout(timer);
if (immediate && !isInvoke) {
fn.apply(this, args);
isInvoke = true;
} else {
timer = setTimeout(() => {
!immediate && fn.apply(this, args);
isInvoke = false;
}, wait);
}
};
}
节流
多次触发,n 秒内执行一次
使用场景
- 监听滚动事件
- DOM 拖拽功能
- 射击游戏
- 计算鼠标移动距离
实现
function throttle(func, wait, options = {}) {
let timeout = 0;
let oldTime = 0;
const { leading = false, trailing = true } = options;
return function (...args) {
let newTime = new Date().valueOf();
if (newTime - oldTime > wait && leading !== false) {
func.apply(this, arguments);
oldTime = newTime;
if (timeout) {
//关键代码块
clearTimeout(timeout);
timeout = 0;
}
}
if (!timeout && trailing !== false) {
timeout = setTimeout(() => {
oldTime = new Date().valueOf(); //关键代码
timeout = 0;
func.apply(this, args);
}, wait);
}
};
}