滚动联动-单独滚动与文档滚动


需求

我们的需求是做一个文档的页面,需要有标题与内容区。左边的标题需要根据内容区来滚动,内容区滚动也需要左边标题区的高亮。这些都是普通文档需要的。

文档标题比较多的时候还需要的是标题区的滚动,标题区滚动是因为当标题过多需要有滚动条,内容区的滚动需要把左边标题区的高亮展示出来。

效果看 dp.bytedance.com,大家手动把浏览器缩小,把左边标题区的滚动条打开

遇到的问题

  1. 我们做的是滚动到某处,选择对应的标题高亮,我们的事件绑定在window.onscroll。问题是我们只滚动左侧标题栏,没有问题,但是当标题栏滚动到最顶或者最后,就开始滚动文档。文档滚动则会带动左侧标题栏的滚动,如果你一直不停的滚动标题栏,就会发现,标题栏的滚动条会乱窜。如下图,如果标题栏再往上滚动,滚动条的位置会被程序改变。

  2. 如图2,左侧的标题栏是是fiexd,footer是absolute的,footer会覆盖一部分标题栏,或者设置标题栏bottom高一些,不过显得难看。

解决方案

  1. 我们的思路是当在左侧导航栏滚动的时候只执行高亮,不做跟随。我们原来的方案是在window的scroll事件上面监听,然后发现这是不行的,无法区分滚动的位置是什么。如何区分滚动的位置是重点。
    后来发现scroll事件并不能满足我们的需求,控制scroll的事件,我们着眼于mousewheel事件,由于本站是pc站,我们只需要操作这个事件就可以。

     document.addEventListener("mousewheel",function(e:any){
        console.log(e.target)
     })

    我们可以知道在何处触发的滚动。
    还有个小操作就是我们知道e.target的dom是不是左边栏。于是我们需要追溯到他们的祖宗元素:

     let target = e.target;
     let leftDom = document.querySelector('.scrollHandle');
     while(target != document.body ){ //找出触发区域
        target = target.parentNode;
        if(target == leftDom){ 
            console.log("is on the left bar");
           break;
        }
     }
  2. 第二个问题我们的解决方案是当页面滚动到底部,我们动态改变左边栏的bottom值。

     const el:any = doc.querySelector(".scrollHandle");
      if(doc.scrollTop+doc.clientHeight >= doc.scrollHeight-60){ //滚动条滚动到footer处
        el.style.bottom = '70px';
      }else{
        el.style.bottom = '10px';
      }

others

dp.bytedance.com是angular2+ts的新尝试

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告