js手写tab栏,添加锚点并巧妙解决固定头部导致的锚点定位问题

2022-03-25  本文已影响0人  游走在城市的鱼

暂未做过多适配,请打开f12用手机模式预览:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
    body {
      overflow: hidden;
      box-sizing: border-box;
    }
    .wrapper {
      box-sizing: border-box;
      width: 375px;
      display: flex;
      background: #ccc;
      overflow-x: auto;
      padding: 15px 0;
      /* 增加平滑滚动效果 */
      scroll-behavior: smooth;
    }
    .wrapper::-webkit-scrollbar {
      display: none;
    } 
    .wrapper span {
      display: inline-block;
      background: #fff;
      border-radius: 20px;
      padding: 3px 10px;
      margin: 0 5px;
      flex-shrink: 0;
    }
    .wrapper span.active {
      background: #000;
      color: #fff;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <span>首页</span>
    <span>精选文章</span>
    <span>推荐</span>
    <span>朋友圈</span>
    <span>生活</span>
    <span>精选文章</span>
    <span>朋友圈</span>
    <span>联系方式</span>
    <span>关于我们</span>
  </div>
  <div class="container">
    主体内容 
  </div>

  <script>
    const spanList = document.querySelectorAll('.wrapper span')
    const wrapper =  document.querySelector('.wrapper')
    wrapper.addEventListener('click', (e) => {
      const target = e.target
      if(!~target.className.indexOf('wrapper')) {
        spanList.forEach(span => span.className = '')
        target.className = 'active'
        const offsetLeft = target.offsetLeft
        const offsetWidth = target.offsetWidth
        wrapper.scrollLeft = offsetLeft - 375/2 + offsetWidth/2
      }
    })
  </script>
</body>
</html>

实现思路:主要计算元素距离外层元素的距离和自身宽度来计算应该滚动到的位置
实现效果:


实现效果.png

实际情况下可能会添加一些锚点,以下为添加锚点的代码和效果:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      body {
        box-sizing: border-box;
        scroll-behavior: smooth;
      }
      .wrapper {
        position: sticky;
        top: 0;
        box-sizing: border-box;
        width: 375px;
        display: flex;
        background: #ccc;
        overflow-x: auto;
        padding: 15px 0;
        /* 增加平滑滚动效果 */
        scroll-behavior: smooth;
      }
      .wrapper::-webkit-scrollbar {
        display: none;
      }
      .wrapper .tab {
        display: inline-block;
        background: #fff;
        border-radius: 20px;
        padding: 3px 10px;
        margin: 0 5px;
        flex-shrink: 0;
        text-decoration: none;
        color: #000;
      }
      .wrapper .tab.active {
        background: #000;
        color: #fff;
      }

      .content {
        padding-top: 60px;
        margin-top: -60px;
        /* border-top: 60px solid transparent; */
        min-height: 400px;
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <a class="tab" href="#home"> 首页 </a>
      <a class="tab" href="#chosen"> 精选文章 </a>
      <a class="tab" href="#tuijian"> 推荐 </a>
      <a class="tab" href="#pengyouquan"> 朋友圈 </a>
      <a class="tab" href="#life"> 生活 </a>
      <a class="tab" href="#jingxuan"> 精选文章 </a>
      <a class="tab">朋友圈</a>
      <a class="tab">联系方式</a>
      <a class="tab">关于我们</a>
    </div>
    <div class="container">
      <div id="home" class="content">
        1.首页<br />首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容首页内容
      </div>
      <div id="chosen" class="content">
        2.精选文章<br />精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章精选文章
      </div>
      <div id="tuijian" class="content">3.推荐<br />推荐</div>
      <div id="pengyouquan" class="content">4.朋友圈<br />朋友圈</div>
      <div id="life" class="content">5.生活<br />生活</div>
      <div id="jingxuan" class="content">6.精选文章<br />精选文章</div>
    </div>

    <script>
      const spanList = document.querySelectorAll(".wrapper .tab");
      const wrapper = document.querySelector(".wrapper");
      wrapper.addEventListener("click", (e) => {
        const target = e.target;
        if (!~target.className.indexOf("wrapper")) {
          spanList.forEach((span) => (span.className = "tab"));
          target.className = "tab active";
          const offsetLeft = target.offsetLeft;
          const offsetWidth = target.offsetWidth;
          wrapper.scrollLeft = offsetLeft - 375 / 2 + offsetWidth / 2;
        }
      });
    </script>
  </body>
</html>

其中使用了padding-top:60px;margin-top:-60px;技巧解决了锚点的适配问题


添加锚点后的效果图.png
上一篇 下一篇

猜你喜欢

热点阅读