vue项目--导航栏固定:实现页面滑动到相应位置导航栏有相应选中效果;点击导航栏跳转到对应位置;

1、我们先写好我们的html结构,一个nav导航栏

<div class="product_nav">
      <div class="product_nav_box1 scollNavItem" :class="{ 'product_nav_box_active' is_Active === 1 }"
        @click="skipTo('.product_cont2', 1)">个性化定制</div>
      <div class="product_nav_box2 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 2 }"
        @click="skipTo('.product_cont3', 2)">数据运营</div>
      <div class="product_nav_box3 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 3 }"
        @click="skipTo('.product_cont4', 3)">学员订单管理</div>
      <div class="product_nav_box4 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 4 }"
        @click="skipTo('.product_cont5', 4)">退款明细</div>
      <div class="product_nav_box5 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 5 }"
        @click="skipTo('.product_cont6', 5)">分校区管理</div>
</div>

  2、设置我们的样式

 .product_nav {
      display: flex;
      width: 80%;
      height: 6.25rem;
      position: absolute;
      left: 10%;
      top: 26.875rem;
      background-color: #fff;
      border-radius: 1.6875rem 1.6875rem 1.6875rem 1.6875rem;
      overflow: hidden;
      box-shadow: 0.4375rem 0.4375rem 0.75rem rgba(0, 0, 0, 0.4),
        -0.4375rem -0.4375rem 0.75rem rgba(255, 255, 255, 0.9);

      .product_nav_box1,
      .product_nav_box2,
      .product_nav_box3,
      .product_nav_box4,
      .product_nav_box5 {
        cursor: pointer;
        text-align: center;
        line-height: 6.25rem;
        width: calc(100% / 7);
        height: 100%;
        font-size: 24px;
        color: #333;
        font-weight: 400;
      }

      .product_nav_box4 {
        border-radius: 0 1.6875rem 1.6875rem 0;
      }

      .product_nav_box5 {
        border-radius: 1.6875rem 0 0 1.6875rem;
      }

      .product_nav_box_active {
        background: linear-gradient(270deg, #2A8DFC 0%, rgba(35,127,251,0.59) 74%, #B5CEFF 100%);
        color: #fff;
      }
    }
    
    .is_noShow {
      opacity: 0;
      transition: all .8s;
    }
    .is_Show {
      opacity: 1;
      transition: all .8s;
    }
    .is_fixed {
      text-align: center;
      position: fixed;
      top: 5.375rem;
      left: 10%;
      z-index: 98;
      width: 80%;
      height: 100px;
      border-radius: 1.6875rem 1.6875rem 1.6875rem 1.6875rem;
      background-color: #fff;
      .scollNavItem {
        line-height: 100px;
      }
    }

3、 设置锚点和nav

  mounted () {
    //监听滚动
    window.addEventListener('scroll', this.fiexdNav)
  },
data () {
    return {
      isFixed: false,
      scrollTop: 430,  //距离顶部的距离
      offsetTop: 0
    }
  },
   // 固定nav,页面滑动,锚点选中
   fiexdNav () {
      const scrollTop = document.documentElement.scrollTop  || document.body.scrollTop
      // console.log(scrollTop)
      const nav = document.querySelector('.product_nav')
      if (scrollTop > this.scrollTop) {
        nav.classList.add('is_fixed')
      }
      if(scrollTop >= 6609) {
        nav.classList.add('is_noShow')
      }else if(scrollTop <= 6609) {
        nav.classList.remove('is_noShow')
      }
      if(scrollTop < this.scrollTop){
        nav.classList.remove('is_fixed')
      }
      //  获取所有锚点元素
      const contents = document.querySelectorAll('.scollItem')
      //  锚点收集
      const contentsOffsetTop = []
      contents.forEach(item => {
        contentsOffsetTop.push(item.offsetTop)
      })
      const pageHeight = window.innerHeight
      //  获取nav的子元素
      const navChildren = document.querySelectorAll('.scollNavItem')
      for (let i = 0; i < contentsOffsetTop.length; i++) {
        if (i === 0) {
          navChildren[0].classList.add('product_nav_box_active')
        } else if (scrollTop > contentsOffsetTop[i - 1] + pageHeight / 3) {
          for (let j = 0; j < contentsOffsetTop.length; j++) {
            // 排他
            navChildren[j].classList.remove('product_nav_box_active')
            navChildren[i].classList.add('product_nav_box_active')
          }
        } else {
          navChildren[i].classList.remove('product_nav_box_active')
        }
      }
    },
    // 点击nav选中锚点元素
    skipTo (selector, active) {
    //  ** 这里是为了调整页面的布局,当选中第一个items的时候,nav并没有贴在页面的最顶端
    //  ** navHeight + 86 所以在这里多减去一个nav的高度。
      if (active == 6) {
        this.listBoxState = true
        const navHeight = document.querySelector('.product_nav').offsetHeight
        const target = document.querySelector(selector)
        target.scrollIntoView({ behavior: 'smooth' })
        window.scrollTo({top:target.offsetTop - navHeight + 86,behavior:'smooth'})
      }else {
        const navHeight = document.querySelector('.product_nav').offsetHeight
        const target = document.querySelector(selector)
        target.scrollIntoView({ behavior: 'smooth' })
        // ** behavior:'' 是定义锚点滚动时候一个切换效果,
        // ** 默认的是auto。直接切换
        // ** smooth,平滑过渡                          
        window.scrollTo({top:target.offsetTop - navHeight, behavior: 'smooth'})
      }
    },
  },
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值