Vue-- 锚点实现左右两栏联动--scrollIntoView方法

官网:scrollintoView
通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视窗中。
利用scrollIntoView() 函数 默认是true
document.getElementById(需要滚动的div的id).scrollIntoView()
如果给该方法传入true作为参数,或者不传入任何参数,那么 窗口滚动之后会让调动元素顶部和视窗顶部尽可能齐平。
如果给该方法传入false作为参数,调用元素会尽可能全部出现在视口中(可能的话,调用元素的底部会与视口的顶部齐平)不过顶部不一定齐平。

代码实现

// vue
<template>
  <div class="panelBlock flex">
    <div class="panelLeft" ref="anchorRef" @scroll="handleScroll">
      <div class="panelItem anchorItem" ref="anchor0">
        <div class="panelItemTitle">内容标题1</div>
        <div class='panelItemContent'>
          描述描述描述描述描述描述描述
        </div>
      </div>
     <div class="panelItem anchorItem" ref="anchor1">
        <div class="panelItemTitle">内容标题2</div>
        xxx
      </div>
      <div class="panelItem anchorItem" ref="anchor2">
        <div class="ppanelItemTitle">内容标题3</div>
        <div class="panelItemContent">
         描述描述描述描述描述描述描述
        </div>
      </div>
      <div class="panelItem anchorItem" ref="anchor3">
        <div class="panelItemTitle">内容标题4</div>
        <div class="panelItemContent">
         描述描述描述描述描述描述描述
        </div>
      </div>
    </div>
    <div class="panelRight">
      <div class="stepLine"></div>
      <ul>
        <li
          v-for="(item, index) in stepData"
          :key="index"
          :class="{ 'stepActive': activeBtn == index }"
          @click="goAnchor('anchor' + index, index)"
        >
          <div class="stepIcon"></div>
          <div class="stepLabel">{{ item }}</div>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
// js
export default {
  data() {
    return {
      activeBtn: 0, //锚点按钮
      stepData: ['标题1', '标题2', '标题3', '标题4'],
    }
  },
  methods: {
    //锚点跳转
    goAnchor(dom, index) {
      this.activeBtn = index
      this.$refs[dom][0].scrollIntoView({ behavior: 'smooth' })
    },
    // 滚动监听器
    handleScroll() {
      // 获取所有锚点元素
      const navContents = document.querySelectorAll('.anchorItem')
      // 所有锚点元素的 offsetTop
      const offsetTopArr = []
      navContents.forEach((item) => {
        offsetTopArr.push(item.offsetTop)
      })
      // 获取当前文档流的 scrollTop
      const scrollTop = this.$refs.anchorRef.scrollTop
      offsetTopArr.forEach((item, index) => {
        if (scrollTop >= item) {
          this.activeBtn = index
        }
      })
    },
  }
}
</script>
// css
<style lang="less">
.panelBlock{
    height: 100%;
    .panelLeft {
      width: calc(100% - 180px);
      overflow-y: auto;
      height: 100%;
      . panelItem{
        .panelItemContent {
          padding: 10px;
          border-top: 0;
          min-height: 40px;
          }
        }
      }
    }
    .panelRight {
      padding-top: 10px;
      position: fixed;
      left: calc(100% - 210px);
      .stepLine {
        position: absolute;
        left: 6px;
        top: 0;
        width: 1px;
        background: #dcdfe6;
        height: calc(50vh - 85px);
        z-index: 0;
      }
      ul {
        li {
          padding-bottom: 20px;
          .stepIcon {
            width: 13px;
            height: 13px;
            margin-right: 20px;
            border-radius: 50%;
            z-index: 1;
          }
          .stepLabel {
            font-weight: 700;
            font-size: 14px;
            line-height: 22px;
            color: #303133;
          }
        }
        .stepActive {
          .stepIcon{
            border: 1px solid #1989fe;
            background: #fff;
          }
          .stepLabel {
            color: #1989fe;
          }
        }
      }
    }
  }
</style>

可能报错

this. r e f s . i t e m 1. s c r o l l I n t o V i e w i s n o t a f u n c t i o n , t h i s . refs.item1.scrollIntoView is not a function,this. refs.item1.scrollIntoViewisnotafunctionthis.refs[dom].scrollIntoView is not a function

在这里插入图片描述

原因

在这里插入图片描述
获取的ref是一个数组,故而获取不到对应方法

修改
// 原代码
this.$refs[dom].scrollIntoView({behavior:'smooth'}// 修改后代码
this.$refs[dom][0].scrollIntoView({behavior:'smooth'}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hyduan200

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值