我们的需求是做一个文档的页面,需要有标题与内容区。左边的标题需要根据内容区来滚动,内容区滚动也需要左边标题区的高亮。这些都是普通文档需要的。
文档标题比较多的时候还需要的是标题区的滚动,标题区滚动是因为当标题过多需要有滚动条,内容区的滚动需要把左边标题区的高亮展示出来。
效果看 dp.bytedance.com,大家手动把浏览器缩小,把左边标题区的滚动条打开
我们做的是滚动到某处,选择对应的标题高亮,我们的事件绑定在window.onscroll。问题是我们只滚动左侧标题栏,没有问题,但是当标题栏滚动到最顶或者最后,就开始滚动文档。文档滚动则会带动左侧标题栏的滚动,如果你一直不停的滚动标题栏,就会发现,标题栏的滚动条会乱窜。如下图,如果标题栏再往上滚动,滚动条的位置会被程序改变。
如图2,左侧的标题栏是是fiexd,footer是absolute的,footer会覆盖一部分标题栏,或者设置标题栏bottom高一些,不过显得难看。
我们的思路是当在左侧导航栏滚动的时候只执行高亮,不做跟随。我们原来的方案是在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;
}
}
第二个问题我们的解决方案是当页面滚动到底部,我们动态改变左边栏的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';
}
dp.bytedance.com是angular2+ts的新尝试
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。