一.防抖和节流
防抖 : 就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间
节流 : 指连续触发事件但是在 n 秒中只执行一次函数。 会稀释函数的执行频率。
二.常见使用场景
例如:连续点击商品加入购物车
我们不需要使用用户每次点击加入购物车都发送ajax来触发,我们仅仅需要用户最后一次的点击或者用户在短时间不点击的时候发送请求,这个时候就可以用到防抖(debounce)
例如:游戏中的技能冷却,一直点击技能键冷却时间结束后触发
为了防止频繁操作加以限制,在一直触发的情况下每隔一段时间后才触发一次,我们可以使用节流(throttle)
三.结合需求代码实现
简单的介绍防抖,大家应该稍微了解了一下什么是防抖,我们现在模拟一个防抖场景,使用一下 用户在input框输入内容的时候,每次输入内容我们都获取input内容发送请求到服务器来返回对应的信息,但是这样太浪费服务器资源了,我们可以使用防抖,在用户不输入的时候或者用户一段时间不输入的时候在发送请求
防抖代码
doucment.querySelector('input').onkeyup = function(){
if(this.value) return
if(this.time) clearsetTimeout(this.time)
this.time = setTimeout(()=>{
console.log(this.value)
console.log('发送请求')
},300)
}
复制代码
不难看出上述代码使用setTimeout来延迟执行,如果用户在300毫秒以内又再次触发了keyup事件,那么我们就清除setTimeout来达到中断事件发生
节流代码
计时器实现
document.onmousemove = function (){
if(!this.time){
this.time = setTimeout(()=>{
cnsole.log('throttle')
this.time = null
},1000)
}
}
复制代码
节流的实现先对来说比防抖很好理解,在一段时间后我们清空定时器再去执行定时器,在等待时间会重复触发计时器 时间戳实现
未完待续
复制代码
四.使用函数封装
需求实现了,为了代码的复用性,我们把他们封装成函数,由于time这个变量为了不让他污染全局,我们可以使用闭包的手法把他变成局部变量
封装防抖
function debounce(fn, delay) {
var timer
return function () {
if(timer) clearTimeout(timer)
timer = setTimeout( ()=>{
fn.apply(this, arguments)
}, delay)
}
}
function foo(){
console.log(this.value)
}
document.querySelector('input').onkeyup = debounce(foo,300)
复制代码
封装节流
function throttle(fn,wait){
var timer
return function(){
if(!timer){
timer = setTimeout(()=>{
fn.apply(this,arguments)
timer = null
},wait)
}
}
}
function foo(){
console.log('throttle')
}
document.onmousemove = throttle(foo,1000)
复制代码
五.总结
debounce 强制函数在某段时间内只执行一次,throttle 强制函数以固定的速率执行。在处理一些高频率触发的 DOM 事件的时候,它们都能极大提高用户体验。在以后的面试中和生产项目中都会频繁的遇上。本文只是简单的介绍了一下防抖和节流,如有不正,请添加评论我及时改正