JavaScript Debouncing与Throttling
这周还遇到了一个问题,在遇到了overflow坑之后,我准备自己实现以下滚动效果,第一是滚动条太难看,第二是overflow无法达成我要的效果。
所以就找到了wheel
事件想要借此来自己实现滚动,结果一监听就坑了,我发现只要稍微移一下就会触发一次事件,那样一秒可以触发上百次了吧,尤其是使用触摸板的时候还有惯性——根本停不下来。
之后就接触到了解决方案:
参考:http://stackoverflow.com/questions/3515446/jquery-mousewheel-detecting-when-the-wheel-stops
if (event.deltaY === 0) return;
if (!this.wheel) {
console.log('start wheel');
}
clearTimeout(this.wheel);
this.wheel = setTimeout(() => {
console.log('stop');
this.wheel = undefined;
this.wheeldelta.x = 0;
this.wheeldelta.y = 0;
}, 250);
this.wheeldelta.x += event.deltaX;
this.wheeldelta.y += event.deltaY;
console.log(this.wheeldelta);
当时我想的确实也差不多,只是不太清楚定时器是否靠谱,既然大家都这么实现的那就用吧——当然,其实这就是debouncing
。
原理的代码其实大家都能看懂,无非也就是如果持续触发就取消上一次注册的定时器,如果没有取消就代表停止了,停止之后执行对应的函数。
在debouncing之前,过去也有解决方案,也是通过定时器,只是思路稍微不太一样,是通过定时检测状态来实现的。
var outerPane = $details.find(“.details-pane-outer”),
didScroll = false;
$(window).scroll(function() {
didScroll = true;
});
setInterval(function() {
if ( didScroll ) {
didScroll = false;
// Check your page position and then
// Load in more results
}
}, 250);
setInterval这种根本停不下来的东西总是让人有点不太舒服。
还有一种东西叫做Throttling,有人肯定觉得,既然有了Debouncing,那不就够了吗,为什么还要Throttling呢?
Debouncing必须要保证操作停止了才准备触发,而Throttling则可以保证一段时间内触发一次。Throttle就有点像上面给的那段代码的效果了。
当然,开源库是有的,我们不用重复造轮子,直接用开源库就行了。
扩展阅读:
http://jinlong.github.io/2016/04/24/Debouncing-and-Throttling-Explained-Through-Examples/
植入部分
如果您觉得文章不错,可以通过赞助支持我。
如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。