这两个东西,你肯定听过,就是两种优化浏览器性能的手段。相关文章你肯定也看过,如果还是不太清楚,没关系,看完这篇短文,相信你能轻松理解其中差别。
首先来看看防抖,用一个比较形象的比喻
防抖,就像是公交车司机,到站停车以后,默认等15秒关闭车门发动,如果在第14秒的时候来了一位乘客,会重新等待15秒再关门,如果在这15秒内又来了乘客,继续等待新的15秒
(你可能会说,要是有很多坏蛋,排着队,每隔14秒就跑过来上车怎么办……)
虽然可能存在上面括号里的漏洞,但是我们可以这样来理解防抖:给一个固定时间,如果你开始触发动作,并且在这个固定时间内不再有任何动作,我就执行一次,否则我每次都会重新开始计时。
理解了防抖,节流其实就容易了。防抖是对频繁发生的事件,每次都重新计时,在时间段内没有事件触发则执行,有触发则继续重置时间计时。再结合上面的故事:
“假设这辆公交车上有个售票员,每上来一个人,都会广播下一站和终点站。结果他发现连着上来10个人,自己要连续播10次,这样嗓子就废了。于是他想了个办法,上来乘客的时候,播放一次,如果在10秒内,连续有多个乘客上车,他也只播放一次。第11秒的时候,有新乘客上车了,再播放一次。完美解决嗓子问题。
”
再来简单总结下节流的含义:用户会反复触发一些操作,比如鼠标移动事件,此时只需要指定一个“巡视”的间隔时间,不管用户期间触发多少次,只会在间隔点上执行给定的回调函数。,我们同样可以用极端情况来理解:如果给定的间隔时间是 240毫秒,用户永不间断地在屏幕上疯狂移动鼠标,那么你的回调函数会分别在 240毫秒、 480毫秒、 720毫秒... 就这么一直执行下去。
“节流通常用在比防抖刷新更频繁的场景下,而且大部分是需要涉及动画的操作。
”
var debounce = function (fn, delayTime) {
var timeId;
return function() {
var context = this, args = arguments;
timeId && clearTimeout(timeout);
timeId = setTimeout(function{
fn.apply(context, args);
}, delayTime)
}
}
const handlerChange = debounce(function () {alert('更新触发了')})
// 绑定监听
document.querySelector("input").addEventListener('input', handlerChange);
var throttle = function (fn, delayTime) {
var flag, _start = Date.now();
return function () {
var context = this,args = arguments, _now = Date.now(), remainTime = delayTime - (_now - _start);
if (remainTime <= 0 ) {
fn.apply(this, args);
} else {
setTimeout(function () {
fn.apply(this, args);
}, remainTime)
}
}
}
let handleMouseMove = throttle(function(e) {
console.log(e.pageX, e.pageY);
})
// 绑定监听
document.querySelector("#panel").addEventListener('mousemove', handleMouseMove);
最后,给“前端面试题宝典”的辅导服务打下广告,目前有简历指导、模拟面试和面试全流程跟踪的增值服务,如果有感兴趣的伙伴,可以联系小助手(微信号:interview-fe)了解详情。