原生JS控制多个滚动条同步跟随滚动效果(2)

似乎很不错,但是现在是不仅想让右边跟随左边滚动,还想左边跟随右边滚动,于是再加以下代码:

addEventListener('scroll',function(){
 r.scrollTop = l.scrollTop
})

看上去很不错,然而,哪有那么简单的事情。

这个时候你再用鼠标滚轮进行滚动的时候,却发现滚动得有点吃力,两个容器元素的滚动似乎被什么阻碍住了,很难滚动。

仔细分析,原因很简单,当你在左边滚动的时候,触发了左边的滚动事件,于是右边跟随滚动,但是与此同时右边的跟随滚动也是滚动,于是也触发了右边的滚动,于是左边也要跟随右边滚动...然后就进入了一个类似于相互触发的情况,所以就会发现滚动得很吃力。

解决 scroll 事件同时触发的问题

想要解决上述问题,暂时有以下两种方案。

将 scroll 事件换成 mousewheel 事件

由于 scroll 事件不仅会被鼠标主动滚动触发,同时改变容器元素的 scrollTop 也会触发,元素的主动滚动其实就是鼠标滚轮触发的,所以可以将 scroll 事件换成一个对鼠标滚动敏感而不是元素滚动敏感的事件:'mousewheel',于是上述监听代码变成了:

addEventListener('mousewheel',function(){
  r.scrollTop = l.scrollTop
})
r.addEventListener('mousewheel',function(){
  l.scrollTop = r.scrollTop
})

效果如下:

似乎是有点用,但是实际上还有两个问题。

当滚动其中一个容器元素的时候,另外一个容器元素虽然也跟着滚动,但滚动得并不流畅,高度有明显的瞬间弹跳

在网上找了一圈,没有找到关于 wheel 事件滚动频率相关内容,我推测这可能就是此事件的一个 feature

鼠标每次滚动基本上都并不是以 1px 为单位的,其最小单元远比 scroll 事件小的多,我用我的鼠标在 chrome 浏览器上滚动,每次滚过的距离都恰好是 100px ,不同的鼠标或者浏览器这个数值应该都是不一样的,而 wheel 事件其实真正监听的是鼠标滚轮滚过一个齿轮卡点的事件,这也就能解释为何会出现弹跳的现象了。

一般来说,鼠标滚轮每滚过一个齿轮卡点,就能监听到一个 wheel 事件,从开始到结束,被鼠标主动滚动的元素已经滚动了 100px

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/232.html