防抖
在事件被触发n秒后再执行回调函数(被称为延迟执行)。如果这n秒内再触发事件,则重新开始计时。
我的简单理解:
设置某一事件触发后不会立即执行,而是触发后等待(隔)一段时间再执行(设置一个定时器计时)。如果在这一等待时间中,该事件又再次被触发,则这个定时器将重新开始计时。
应用场景
- 滚动条监听
功能需求描述:监听浏览器滚动事件,返回当前滚动条与顶部的距离 代码很简单:
function showTop(){
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop
console.log('滚动条位置:' + scrollTop)
}
window.onscroll = showTop
但是!这个函数的默认执行频率,太!高!了!。 高到什么程度呢?以chrome为例,我们可以点击选中一个页面的滚动条,然后点击一次键盘的【向下方向键】,会发现函数执行了 8-9次!
然而实际上我们并不需要如此高频的反馈,毕竟浏览器的性能是有限的,不应该浪费在这里,所以接着讨论如何优化这种场景。
这个时候可以使用防抖函数来优化。
- 设置滚动事件触发后不会立即执行,等待200ms之后再执行
- 如果这200ms内,滚动事件再次被触发,那么定时器重新开始计时 我们看一下优化后的代码:
function showTop(){
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop
console.log('滚动条位置:' + scrollTop)
}
function debounce(callback, delay){
//声明一个timer用来保存定时器的id
let timer;
return function(){
clearTimeout(timer)
timer = setTimeout(function(){
callback()
}, delay)
}
}
let debounceFunc = debounce(showTop, 1000)
window.onscroll = debounceFunc
这代码让我写,我肯定写不出来,不知道为什么,js代码总给我一种需要先记住怎么写,再想办法理解的感觉。可能是因为我菜😢
参考🔗:浅谈 JS 防抖和节流
- 监听输入框输入(
input)
功能需求描述:要求输入框输入完成之后,在控制台打印输入的数据 简单实现:
var input = document.getElementById("input");
input.addEventListener('input', function(e){
console.log(e.target.value)
})
上述代码运行结果:
我在输入框里输入
明天我们一起去吃饭,控制台应该等待输入完成之后,再打印'我们一起去吃饭'这句话。可以看到运行结果并不是我们想要的。
使用防抖函数优化后的代码:
var input = document.getElementById("input");
function fn(value){
console.log(value)
}
function debounce(callback, delay){
let timer
return function(value){
clearTimeout(timer)
timer = setTimeout(function(){
callback(value)
}, delay)
}
}
let debounceFunc = debounce(fn, 1000)
input.addEventListener('input', function(e){
debounceFunc(e.target.value)
})
封装防抖函数
function debounce(callback, delay){
let timer
return function(value){
clearTimeout(timer)
timer = setTimeout(function(){
callback(value)
}, delay)
}
}
节流
就是指连续触发事件但是在 n 秒中只执行一次函数。 节流会稀释函数的执行频率。
参考🔗:函数防抖和节流,原博主讲得很好。