CodeSky 代码之空

随手记录自己的学习过程

JavaScript Debouncing与Throttling

2016-08-07 15:52分类: JavaScript评论: 0

这周还遇到了一个问题,在遇到了overflow坑之后,我准备自己实现以下滚动效果,第一是滚动条太难看,第二是overflow无法达成我要的效果。

所以就找到了wheel事件想要借此来自己实现滚动,结果一监听就坑了,我发现只要稍微移一下就会触发一次事件,那样一秒可以触发上百次了吧,尤其是使用触摸板的时候还有惯性——根本停不下来。

之后就接触到了解决方案:

参考:http://stackoverflow.com/questions/3515446/jquery-mousewheel-detecting-when-the-wheel-stops

1   if (event.deltaY === 0) return;
2
3   if (!this.wheel) {
4     console.log('start wheel');
5   }
6   clearTimeout(this.wheel);
7   this.wheel = setTimeout(() => {
8     console.log('stop');
9     this.wheel = undefined;
10     this.wheeldelta.x = 0;
11     this.wheeldelta.y = 0;
12   }, 250);
13
14   this.wheeldelta.x += event.deltaX;
15   this.wheeldelta.y += event.deltaY;
16   console.log(this.wheeldelta);
17

当时我想的确实也差不多,只是不太清楚定时器是否靠谱,既然大家都这么实现的那就用吧——当然,其实这就是debouncing

原理的代码其实大家都能看懂,无非也就是如果持续触发就取消上一次注册的定时器,如果没有取消就代表停止了,停止之后执行对应的函数。

在debouncing之前,过去也有解决方案,也是通过定时器,只是思路稍微不太一样,是通过定时检测状态来实现的。

1var outerPane = $details.find(“.details-pane-outer”),
2	  didScroll = false;
3
4$(window).scroll(function() {
5	didScroll = true;
6});
7
8setInterval(function() {
9	if ( didScroll ) {
10	didScroll = false;
11	// Check your page position and then
12	// Load in more results
13}
14}, 250);
15

setInterval这种根本停不下来的东西总是让人有点不太舒服。

还有一种东西叫做Throttling,有人肯定觉得,既然有了Debouncing,那不就够了吗,为什么还要Throttling呢?

Debouncing必须要保证操作停止了才准备触发,而Throttling则可以保证一段时间内触发一次。Throttle就有点像上面给的那段代码的效果了。

当然,开源库是有的,我们不用重复造轮子,直接用开源库就行了。

扩展阅读:

http://jinlong.github.io/2016/04/24/Debouncing-and-Throttling-Explained-Through-Examples/

评论 (0)