功能点

仿京东内容上下滚动,吸顶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);
上一篇 下一篇

猜你喜欢

热点阅读