防抖
为什么要做防抖
有的操作是高频触发的,但是其实触发一次就好,比如说我们要监听页面缩放,那么我们不应该每次在页面监听到resize时执行操作,应该在停止resize一段时间后执行函数,再比如监听输入框输入,不应该每次的去触发监听,应该等用户完成输入后一段事件后进行触发
总结: 等用户高频事件完了,再进行事件操作
防抖该怎么做
事件触发,先开启一个计时器,假设我给一秒,如果在这一秒内再次触发,就会清除上一个定义的定时器,达到只有最后一次计数器可以运行的效果
//fn传入一个函数,delay写延迟时间
function debounce(fn,delay){
//初始化计时器
let timer = null;
return function() {
clearTimeout(timer);
const args=Array.prototype.slice.call(arguments);
timer = setTimeout(() => {
fn.apply(this, agrs);
}, delay)
}
}
}
需要传参的debounce用法
function sum(a, b) {
console.log(a + b);
}
//需要传参的防抖函数做法
var newSum = debounce(sum, 1000).bind(this, 1, 2);
window.onclick = newSum;
节流
为什么要节流
防抖存在一个问题,事件会一直等到用户完成操作后一段事件才会再操作。如果一直操作,会一直发不触发,假设现在有一个按钮,我点击发送请求,如果一直点请求就发不出去。这里思路就是点击按钮,发送请求,在请求回来之前按钮无效,直到上一次请求回来,才能发出去。
总结: 某一操作希望上一次的完成后在进行下一次,或者说希望隔一定时间触发一次
节流怎么做
事件触发,首先我们执行操作,操作完成,关闭阀门,再阀门开启时间里,我们操作是无效的,操作完成之后,我们又开启阀门,操作可以再次执行;
function throttle(fn, delay) {
// 定义一个阀门
let valid = true;
return function() {
if (valid) {
// 通过阀门开启节流
// 一定时间后阀门关闭执行一次
setTimeout(() => {
fn.apply(this, arguments);
valid = true;
}, delay)
valid = false
} else {
return false;
}
}
}
总结
防抖和节流相同点
防抖和节流都是为了阻止高频触发,从而浪费性能。
防抖和节流不同点
防抖是让你多次触发,只生效最后一次。适用我们只需要一次触发的场景需求;
节流是让你操作,每隔一段时间才能触发一次,适用于多次触发多次生效的场景(触发次数!=生效次数)