Vue实现导航栏绑定内容锚点+滚动动画+vue-router

文章介绍了在开发中遇到的锚点定位侧边栏的需求,通过监听滚动事件,动态计算DOM元素的位置,实现导航高亮。同时,通过平滑滚动函数处理页面上、下滚动到目标位置,确保元素不被固定头部遮挡。在页面刷新时,使用beforeunload事件处理滚动位置,保持导航与内容同步。
摘要由CSDN通过智能技术生成

最近开发的时候,遇到这么一个需求,锚点定位侧边栏,先上图

这个功能一开始看上去就觉得简单,不就是锚点定位嘛,上代码,但是需要注意一些小细节

  data() {
    return {
      highLight: 0,
    }
  },
// 首先监听页面的滚动事件
  mounted() {
    window.addEventListener('scroll', this.onScroll, false)
  },
  methods: { 
    onScroll() {
      const navContents = document.querySelectorAll('.name') // 获取所有需要需要锚点定位的DOM元素
      const offsetTopArr = []
      navContents.forEach(item => {
        offsetTopArr.push(item.offsetTop)   // 获取上面DOM元素距离顶部的距离
      })
      const scrollTop = document.documentElement.scrollTop || document.body.scrollTop // 获取页面滚动了距离
      let navIndex = 0
      for (let n = 0; n < offsetTopArr.length; n++) {
        if (scrollTop >= offsetTopArr[n] - 200) { // 下面介绍为啥-200
          navIndex = n       
        }        
      }
      this.highLight = navIndex
    },
  }
// 锚点定位会将对应的元素定位到页面顶部,由于本人当前页面的头部导航是fixed布局,当锚点在顶部时
// 锚点对应的元素就被导航遮挡住了,所以减去200,让我们锚点元素不被遮挡展示出来

上面的代码就实现了当页面滚动时,滚动不同的距离,其对应的导航会高亮,接下来是切换右侧导航时页面滚动到对应位置

  methods: {
    scrollTo(index) {
// 获取高亮导航对应的锚点定位元素的 offsetTop      
      let targetOffsetTop
      if (index == 0) {
        targetOffsetTop = this.$refs.oneBox1.offsetTop
      } else if (index == 1) {
        targetOffsetTop = this.$refs.oneBox2.offsetTop
      } else if (index == 2) {
        targetOffsetTop = this.$refs.oneBox3.offsetTop
      } else if (index == 3) {
        targetOffsetTop = this.$refs.oneBox4.offsetTop
      } else if (index == 4) {
        targetOffsetTop = this.$refs.oneBox5.offsetTop
      }
// 获取当前页面的 offsetTop
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
      if (scrollTop > targetOffsetTop) {  判断需要往上滚动还是往下滚动
        smoothUp()  
      } else {
        smoothDown()
      }
 
      const STEP = 50
      function smoothDown() {
        if (scrollTop < targetOffsetTop - 150) { // 下面介绍为啥-150
          if (targetOffsetTop - scrollTop >= STEP) {
            scrollTop += STEP
          } else {
            scrollTop = targetOffsetTop
          }
// 给页面的滚动距离重新设置,然后调用方法是页面平滑滚动
          document.body.scrollTop = scrollTop
          document.documentElement.scrollTop = scrollTop
          requestAnimationFrame(smoothDown)  
        }
      }
// 由于上面我们-200的头部导航距离,所以这里我们需要减少一定的值,由于在该项目上一开始-200会导致定位有点怪异,-150却比较正常
      function smoothUp() {
        if (scrollTop > targetOffsetTop) {
          if (scrollTop - targetOffsetTop >= STEP) {
            scrollTop -= STEP
          } else {
            scrollTop = targetOffsetTop
          }
          document.body.scrollTop = scrollTop - 150
          document.documentElement.scrollTop = scrollTop - 150
          requestAnimationFrame(smoothUp)
        }
      }
    }
 }

就这样,我们可以实现头部不被遮挡且平滑滚动的锚点定位啦。最后指出一个小bug,当你刷新页面时,数据都被重置了,但页面滚动的距离会被保留,导致右侧导航高亮没有对应。所以,我们新增下面的方法

  mounted() {
    window.addEventListener('beforeunload', (e) => {
      window.scroll({
        top: 0,
        left: 0,
        behavior: 'smooth'
      });
    })
  }

最后

感谢你的阅读~

如果你有任何的疑问欢迎您在后台私信,我们一同探讨学习!

如果觉得这篇文章对你有所帮助,点赞、在看是最大的支持!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值