似乎很不错,但是现在是不仅想让右边跟随左边滚动,还想左边跟随右边滚动,于是再加以下代码:
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