防抖 debounce
在指定的一段时间内,频繁触发事件,只处理最后一次
通常用在搜索框的联想词,在用户输入完之后,才会出现联想词
不使用防抖,每输入一个字,都会重新联想
这样用户体验会更好,但是相对的服务端需要处理的请求就会增加
// <button>点击我</button>
const btn = document.querySelector('button')
初始版本
每次触发事件都会将上一次绑定的定时器清除, 并重新绑定一个定时器
触发事件后500毫秒内没有再次触发就会打印1
btn.addEventListener('click',debounce) // 绑定点击事件
let timer
function debounce(){
clearTimeout(timer) // 清除定时器
timer = setTimeout(function(){ // 绑定定时器
console.log('1')
},500)
}
完整封装版本
利用回调函数和闭包,将事件处理和防抖函数分离,让封装的防抖函数可以复用
box.addEventListener('click',debounce(function(){
console.log(1)
},500))
function debounce(fn,time){
let timer
return function(){
clear(timer)
timer = setTimeout(function(){
fn()
},time)
}
}
节流 throttle
在同一时间内,频繁触发事件,只执行一次
像监听滚动条事件(scroll)、监听窗口变化事件(resize)、鼠标移动事件(mousemove)等等
都是连续触发多次的事件,可以使用节流来限制事件触发时的执行频率
// <button>点击我</button>
const btn = document.querySelector('button')
初始版本
定义一个flag布尔值,每次触发事件时,将flag赋值为true,后面触发的事件就会return
只有当定时器执行后,将flag赋值为false,才会再次打印1(第一次触发事件会立即打印1)
button.addEventListener('click',throttle)
let flag = false;
function throttle(){
if(flag) return;
flag = true;
console.log('1')
seTimeout(function(){
flag = false;
},1000)
}
完整封装版本
利用回调函数和闭包,将事件处理和节流函数分离,让封装的防抖函数可以复用
button.addEventListener('click',throttle(function(){
console.log('1')
},1000))
function throttle(fn,time){
let flag = false;
return function(){
if(flag) return;
flag = true;
fn();
seTimeout(function(){
flag = false;
},time)
}
}