防抖和节流都是为了减少事件频繁触发,从而提升性能。
防抖(debounce):
概念:
指的是在事件触发后,等待一段时间再执行回调。如果在这段时间内事件再次触发,则重新计时。
使用场景:
-
搜索框输入:用户输入时,延迟发送请求,避免频繁请求,只需用户最后一次输入完,再发请求。
-
手机号、邮箱验证输入检测。
手写防抖函数:
核心步骤:
1. 声明一个定时器变量。
2.每次触发事件时先判断是否有定时器了,如果有定时器先清除以前的定时器。
3.如果没有定时器则开启定时器,要存在变量里面。
4.在定时器里面调用要执行的函数。
实现:
<input type="text" class="input">
<script>
function print(){
console.log(this.value);
}
const input = document.querySelector('input')
input.addEventListener('input',debounce(print,1000));
function debounce(fn,t){
let timer;
return function(){
let context = this,args = arguments;
if(timer) clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(context, args);
},t)
}
}
</script>
节流:
概念:
指的是在规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
使用场景:
-
按钮点击:防止用户重复提交表单(如支付按钮)。
手写节流函数:
核心步骤:
1. 声明一个定时器变量。
2.当鼠标每次点击都先判断是否有定时器了,如果有定时器,则不开启新定时器。
3.如果没有定时器则开启定时器,存到变量里面。
定时器里面调用执行的函数。
定时器里面要把定时器清空。
实现:
1.
<button class="btn">点击</button>
<script>
function print(){
console.log("点击了");
}
const btn = document.querySelector('.btn')
btn.addEventListener('click',throttle(print,1000))
function throttle(fn,t){
let timer = null;
return function(){
if(!timer){
let context = this,args = arguments;
timer = setTimeout(()=>{
fn.apply(context,args);
timer = null;
},t)
}
}
}
</script>
2.
<button class="btn">点击</button>
<script>
function print() {
console.log("点击了");
}
const btn = document.querySelector(".btn");
btn.addEventListener("click", throttle(print, 2000));
function throttle(fn, t) {
let curTimer = Date.now();
return function () {
let context = this,
args = arguments;
let nowTime = Date.now();
if (nowTime - curTimer >= t) {
fn.apply(context, args);
curTimer = Date.now();
}
};
}
</script>