两个盒子分别监听scroll事件的问题


    leftEle.addEventListener('scroll', (e) =>{
         rightEle.scrollTop= e.target.scrollTop
    })
                
    rightEle.addEventListener('scroll', (e)=> {
        leftEle.scrollTop= e.target.scrollTop
    })
    

导致鼠标滚轴滑动很慢,应该是两边的scrollTop同时牵制了对方的滚动,有没有办法使用双方滚动隔离同步,但又不牵制

阅读 4.4k
4 个回答

写了一个 demojs代码如下:

let left = document.getElementById('left'),
    right = document.getElementById('right');

// 每次触发滚动事件时标记上相应元素的激活状态,50毫秒后清除
// 这50毫秒内,另一个元素的滚动事件不会被真正执行
// 同时,如果这50毫秒内该元素再次触发了滚动事件,那么将状态清除函数的执行时间继续往后推迟

let isLeftActive = false,
    isRightActive = false,
    timerId = null;
left.addEventListener('scroll', (e)=>{
  if(!isRightActive){
    isLeftActive = true;
    right.scrollTop = e.target.scrollTop; 
    clearTimeout(timerId);
    timerId = setTimeout(
      () => isLeftActive = false,
      50
    );
  }
});
right.addEventListener('scroll', (e) => {
  if(!isLeftActive){
    isRightActive = true;
    left.scrollTop = e.target.scrollTop;
    clearTimeout(timerId);
    timerId = setTimeout(
      () => isRightActive = false, 
      50
    );
  }
});

大致明白你的意思,你是想滚动左边的时候,右边也跟着动?滚动右边的时候,左边也跟着动?然后又想相互不影响?

监控滚动,这种事件属于高频事件,我们不一定每次滚动都要处理,一个优化的方法是,间隔一段时间在处理一次跟着滚动。
你的代码我稍作一点改动

 let leftEle = document.querySelector('#left');
       let  rightEle = document.querySelector('#right');
       let position = 0;
       let timer = null;
       let leftDisabled = false;
       function setRight(e) {
         position = e.target.scrollTop;
         //间隔短暂事件,右侧跟着滚动,让右侧的滚动事件频率下降
         if (!timer) {
            timer = setTimeout(() => {
               rightEle.scrollTop = position;
               timer = null;
            }, 10);
         }
       }
       function setLeft(e) {
        position = e.target.scrollTop;
        if (!timer) {
            timer = setTimeout(() => {
               leftEle.scrollTop = position;
               timer = null;
            }, 10);
         }
       }

       leftEle.addEventListener('scroll', setRight)
                
       rightEle.addEventListener('scroll', setLeft);

效果如下:
图片描述
对比未改动的代码。
图片描述
效果已经很明显了。其它高频事件(鼠标移动等等)的处理很多时候都是如此,这个是页面优化的一个方法。
当然可以使用面的方法实现类似功能:
1、当然也可以用标志位来判断这个滚动是鼠标引起的,还是代码设置的。
2、一侧滚动时,先移除另一侧的滚动监听,另一侧滚动后,在添加监听事件。
原理大都相似。

加一个节流

var timeout = null;
window.addEventListener('scroll', function() {
    if(timeout !== null) clearTimeout(timeout);
    timeout = setTimeout(function() {
        var scrollTop = this.scrollY;
        console.log(scrollTop);
    }.bind(this), 500);
});
推荐问题