仿京东内容上下滚动,吸顶tab紧跟着切换
2021-03-23 本文已影响0人
keknei
上下滚动内容吸顶tab切换效果图最近工作中一个劲儿的出现了这种内容上下滚动,吸顶tab紧跟着切换的效果,并且点击tab会滚动到具体的位置类似锚点,所以我就写了一个记录下来,我们先看下效果图,大概就是这个样子,下面我们开始撸代码
html部分
<body>
<div>
<div class="header"></div>
<div class="tabBox">
<ul class="tabList">
<li class="active">tab1</li>
<li>tab2</li>
<li>tab3</li>
<li>tab4</li>
<li>tab5</li>
</ul>
<div class="fill"></div>
</div>
<div class="contentBox">
<div class="content">content1</div>
<div class="content">content2</div>
<div class="content">content3</div>
<div class="content">content4</div>
<div class="content">content5</div>
</div>
<div class="footer"></div>
</div>
</body>
css部分
如果点击tab页面滚到具体的内容位置的时候想让页面有一种滚动效果,最简单的方法就是给html,body加一个样式 scroll-behavior:smooth; 如果不需要的话就可以去掉
*{
margin:0;
padding:0;
list-style:none;
}
html,body{
scroll-behavior:smooth;
}
.header{
height:50px;
background:red;
}
.tabBox{
height:50px;
}
.tabList{
overflow:hidden;
height:50px;
position:relative;
left:0;
top:0;
background:green;
}
.tabList li{
float:left;
width:50px;
border-left:1px solid #333;
height:100%;
cursor:pointer;
text-align:center;
line-height:50px;
}
.tabList .active{
background:yellow;
}
.tabList li:last-child{
border-right:1px solid #333;
}
.fill{
height:100%;
display:none;
}
.contentBox div{
height:300px;
text-align:center;
line-height:300px;
border:1px solid #999;
}
.footer{
height:500px;
background:blue;
}
js部分
//获取内容list
const aContent=document.querySelectorAll(".contentBox>div");
//获取tab包裹元素
const oTabBox=document.querySelector(".tabList");
let tBoxOffTop=oTabBox.offsetTop;//距离页面顶部距离
//获取tab元素
const aTab=document.querySelectorAll(".tabList li");
//添加点击事件
aTab.forEach((item,index,arr)=>{
item.onclick=function (){
arr.forEach((val,key)=>{
val.classList.remove("active");
});
this.classList.add("active");
let offsetTop=aContent[index].offsetTop;
if(document.documentElement){
document.documentElement.scrollTop=offsetTop;
}else{
document.body.scrollTop=offsetTop;
}
};
});
//获取填充元素,tab吸顶时显示出来填充,防止页面向上抖动
const oFill=document.querySelector(".fill");
//滚动事件
function scrollHandler(){document
let scrollTop=document.documentElement.scrollTop || document.body.scrollTop;
if(scrollTop-tBoxOffTop>=0){//滚动距离大于tabBox离顶部的距离就吸顶,让填充的元素显示出来
oTabBox.style.position="fixed";
oFill.style.display="block";
}else{
oTabBox.style.position="relative";
oFill.style.display="none";
}
//循环内容区的每个模块的offsetTop对比scrollTop
aContent.forEach((el,i,arr)=>{
//因为下面使用到了i+1,所以需要把最后一个分离出来判断
if(scrollTop<arr[arr.length-1].offsetTop){
//如果滚动距离大于当前模块内容的offsetTop并且小于下一个模块内容的offsetTop,那么tab就应该显示这个模块的索引
if(scrollTop>el.offsetTop&&scrollTop<arr[i+1].offsetTop){
aTab.forEach((val,key)=>{
val.classList.remove("active");
});
aTab[i].classList.add("active");
}
}else{
aTab.forEach((val,key)=>{
val.classList.remove("active");
});
aTab[aTab.length-1].classList.add("active");
}
});
}
document.addEventListener("scroll",scrollHandler);