vue 使用scroll实现锚点

22 篇文章 0 订阅

1.最近出来一个新需求,要求滚动分组时右边出现导航栏,可以通过导航栏跳转到相应分组,实现效果如下:在这里插入图片描述
2.首先监听滚动@scroll="scrollEvent",滚动方法实现如下:

// 监听滚动
    scrollEvent (e) {
      this.showMao = true // 显示导航栏
      let scrollItems = document.querySelectorAll('.temp-items')
      for (let i = scrollItems.length - 1; i >= 0; i--) {
        let judge =
          e.target.scrollTop >=
          scrollItems[i].offsetTop - scrollItems[0].offsetTop - 80 // 减去80是我页面布局的原因,视情况而定
        if (judge && this.toMove) { // 右边导航栏跟随滚动
          this.toMove = true
          this.activeStep = i
          this.scrollLabel(`${i}child`)
          break
        }
      }
    },

3.实现导航跟随页面滚动方法


     scrollLabel (e) {
      let _this = this
      let t = 1
      let queryId = document.getElementById(e)
      queryId.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'})

      if (this.timer2) {
        clearInterval(this.timer2)
      }
      // 未滚动后两秒隐藏导航栏
      this.timer2 = setInterval(() => {
        if (t <= 0 && _this.hideMao) {
          clearInterval(_this.timer2)
          _this.showMao = false
          _this.$forceUpdate()
          return
        }
        t--
      }, 1000)
    },

4.实现点击导航栏跳转对应分组:

 jump (e) {
      this.toMove = false
      let queryId = document.getElementById(e)
      this.activeStep = e
      new Promise(
        function (resolve, reject) {
          resolve('成功')
          queryId.scrollIntoView(true)
        },
      ).then(
        (res) => {
          this.toMove = true
        },
      )
    },

data里面变量初始状态

	  activeStep: 0,
      hideMao: true,
      loading: false,
      toMove: true,
      showMao: false,
      timer2: null

5.页面上也通过鼠标移入移出改变导航栏显示隐藏,如下;

<div class="page-container" @scroll="scrollEvent">
        <div class="temp-items" :id="index" v-for="(option, index) in tempList" :key="'temp-'+index">
          <div class="temp-top">
            <div class="top-info">
              <h3 class="top-title">{{option.name}}</h3>
              <div class="top-text">{{option.desc || '暂无题组介绍'}}</div>
            </div>
          </div>
          <div class="temp-fields" v-loading="loading">
            <template-draggable ref="TemplateDraggable"
                                :templateValues="option.fields"
                                :templateId="''+index"
                                :readOnly="crfStatus===1 || proStatus ===0 || !anStatus"
                                :draggable="false"
                                :editorAble="false"
                                v-on:templateBack="templateEdit"
            ></template-draggable>
          </div>
        </div>
        <transition name="fade">
          <div class="maoDian" v-show="showMao" @mouseleave="showMao=false;hideMao=true" @mouseenter="hideMao=false">
            <div v-for="(option, index) in tempList" :style="{color: activeStep === index ? '#1987e1' : '#5c5c5c'}"
                 :key="option.name">
              <span :id="index+'child'" @click="jump(index)">{{option.name}}</span>
            </div>
          </div>
        </transition>
      </div>

6.不过在跳转的时候我没加平滑过渡,原因是加了平滑过渡后,还没滚动完,Promise就执行完成了,toMove 状态就改变了,导致后面滑动页面,导航栏就不随页面滚动到相应目录,效果如下:在这里插入图片描述
希望路过的大佬救救孩子

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值