**防抖(debounce)和节流(throttle)是两种常用的优化高频触发事件的方法。**钙片文章主要是搞清楚防抖与节流函数的代码逻辑,讲解他们在真实项目中的运用与实践
防抖:当持续触发事件时,一定时间段内没有再触发事件,函数才会执行一次,如果在这个时间段内又触发了事件,则会重新开始延时。常用于输入框搜索、滚动加载等场景。
节流:当持续触发事件时,保证一定时间段内只触发一次事件处理函数。常用于滚动监听、窗口大小改变等场景。
防抖debounce
剖析防抖函数的特点 在一段时间内执行多次,但是只有最后一次执行生效
//简化版防抖函数
function debounce(callBack,delay){
let timer = null
clearTimeout(timer)
timer = setTimeout(callBack,delay)
}
这里完成了基本的防抖操作,接下来进阶版本
fucntion debounce(callBack,delay){
let timer = null;
return function (){
const context = this
const args = arguments
clearTimeout(timer)
timer = setTimeout(()=>{
callBack.aplly(context,args)
})
}
}
应用场景实列
1.模糊查询:我们在实际开发中可能会遇到当用户在搜索框中输入时,搜索框下面会出现一片区域,用来展示你通过输入的关键字查询到的一些结果,此时你并不希望一输入内容就开始查询,而是等你输入完成需要查询的内容再去查询
import { onMounted } from "vue";
const inputHandler = (e: Event) => {
console.log((e.target as HTMLInputElement).value);
};
const debounce = <T extends (...args: any[]) => void>(
callBack: T,
delay: number
): ((...args: Parameters<T>) => void) => {
let timer: number | null = null;
return (...args: Parameters<T>) => {
if (timer !== null) {
clearTimeout(timer);
}
timer = window.setTimeout(() => callBack(...args), delay);
};
};
onMounted(() => {
const input = document.getElementById("debouncedInput");
// 将回调函数包装在防抖函数中,设置防抖延迟时间为 300 毫秒
const debouncedHandleInput = debounce(inputHandler, 300);
// 给输入框添加 input 事件监听器
input?.addEventListener("input", debouncedHandleInput);
});
这里能有效优化请求效率
防抖 throttle
通俗来说就是我在一段时间内,按照一定的频率来执行事件,主要是对一些高触发频率的事件结合使用
const throttle = (callBack,delay)=>{
let lastTime = 0 ;
return (...args)=>{
let now = Date.now();
if(now-lastTime>delay){
callBack(args)
lastTime = now
}
}
}
1.场景滚动事件触发
const throttle = <T extends (...args: any[]) => void>(
callBack: T,
delay: number
): ((...args: Parameters<T>) => void) => {
let lastTime = 0;
return (...args: Parameters<T>) => {
let now = Date.now();
if (now - lastTime > delay) {
callBack(...args);
lastTime = now;
}
};
};
onMounted(() => {
const box = document.getElementById("box");
//限制触发频率为间隔500ms触发一下滚动事件
const throttleHandleScroll = throttle(scrollHandler, 500);
box?.addEventListener("scroll", throttleHandleScroll);
});
<div id="box">
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
</div>
#box {
height: 200px;
width: 200px;
overflow: auto;
border: 1px solid #000;
}
#box p {
height: 100px;
margin: 0;
padding: 0;
}
还有鼠标移动事件,mousemove,表单提交频率
//场景二 表单提交按钮
const submitButtonFetch =async()=>{ const result = awiat fetch('./userForm')}
const debounceSubMit = throttle(submitButtonFetch, 500)
btn.addEventListener('click', debounceSubMit)
//其实和添加loading效果一样每间隔一个loading动画时间才能继续提交请求
感谢!!!!