一、引
在前端开发中,会有很多事件是会被多次触发的,onmousemove
、 scroll
、resize
。就对于 scroll
来说,每个像素的滚动都会触发事件,这样滚轮的单次滚动就会触发几十次。经过千度一下发现有防抖函数和节流俩个方法能解决,这样也来学习和总结一下。
简单的写个效果
<script>
let num = 1;
window.addEventListener('scroll',function(){
console.log(num++)
})
</script>
/*大概的效果就是,你的console一栏中,疯狂滚动数字*/
二、防抖函数
我也不知道谁取的这名字。大概的意思就是,这种频繁触发的事件给定个事件区间,在给定的时间区间内只会被触发一次,如果多次触发,则重新计算这个时间区间。
因此分为俩个版本,立即执行和非立即执行版本。
2.1非立即执行
function debounce(func, wait){
let timer == null;
return function(){
if (timer){
cleartimer(timer);
} else {
timer = setTimeout(func, wait);
}
}
}
这里因为要让 timer
常驻内存,所以用到了闭包(如果不懂可以专到我闭包的文章),大概的意思就是在触发事件后函数 1 秒后才执行,而如果我在触发事件后的 1 秒内又触发了事件,则会重新计算函数执行时间。
window.addEventListener('scroll',debounce(function(){
console.log(num++)
},1000))
2.2立即执行
function debounce(func,wait) {
let timer;
let timer = null;
return function () {
if (timer){
clearTimeout(timer);
}
if (!timer){
func()
}
timer = setTimeout(() => {
timer = null;
}, wait)
}
}
效果就是返过来,会先触发事件,然后接下来的 wait 秒内不会触发同样事件,而且在 wait 秒内不再触发同样事件,接下来才可以触发。都不难。
三、节流
这个从名字上还能理解点,比防抖明白点。大概的意思就是少开销嘛,这样函数的思想就是在 n 秒内让他只执行一次。不多BB,直接看代码
function throttle(func, wait) {
let previous = 0;
return function() {
let now = Date.now();
let args = arguments;
if (now - previous > wait) {
func.apply(this, args);
previous = now;
}
}
}
代码没什么好解释的,挺简单的,过~~