vue实现锚点定位(多级动态菜单)

2023-11-01

现在有一个需求是实现多级动态菜单点击跳转到相应位置,一般这种需求实现起来就是href+id的方式锚点定位

但是这种方式的滚动很生硬,故不采纳

我使用的方案是根据id,获取到当前元素距离body顶部的距离,判断此时滚动条需要滚动的距离,再通过

window.scrollTo方法实现平滑滚动到该区域

具体实现方案:

1,定义菜单和内容区域,内容区域的id使用菜单首字母缩写

2,引入js-pinyin插件,识别当前点击菜单的首字母缩写,与内容区域id对应

3,获取内容区域距离body顶部的距离,由于元素offsetTop的计算是根据当前元素相对于最近的定位父元素计算出来的,

所以不能直接用“元素.offsetTop”获取,需要定义一个方法计算当前元素距离body顶部的“真实”距离。

4,通过window.scrollTo并开启平滑滚动

demo:

<template>
  <div>
    <!-- 菜单 -->
    <div class="tabs">
      <span v-for="(item,index) in tabList"
            @click="toTabDetail(item)"
            :key="index">{{ item.title }}</span>
    </div>
    <!-- 公司介绍 -->
    <div class="tab_content"
         id="gsjs">
      <p>公司介绍</p>
    </div>
    <!-- 联系我们 -->
    <div class="tab_content"
         id="lxwm">
      <p>联系我们</p>
    </div>
    <!-- 公司地址 -->
    <div class="tab_content"
         id="gsdz">
      <p>公司地址</p>
    </div>
  </div>
</template>

<script>
import pinyin from 'js-pinyin'
pinyin.setOptions({ checkPolyphone: false, charCase: 1 }); // 1小写0大写,默认大写
export default {
  data () {
    return {
      tabList: [
        {
          title: '公司介绍'
        },
        {
          title: '联系我们'
        },
        {
          title: '公司地址'
        }
      ]
    }
  },
  methods: {
    toTabDetail ({ title }) {
      const id = `#${pinyin.getCamelChars(title)}` // pinyin.getCamelChars获取字符串每个字首字母
      this.$nextTick(() => {
        window.scrollTo({
          top: this.getOffsetTopByBody(document.querySelector(id)),
          behavior: 'smooth' // 开启平滑滚动
        })
      })
    },
    // 获取元素相对于body的高度
    getOffsetTopByBody (el) {
      let offsetTop = 0
      while (el && el.tagName !== 'BODY') {
        offsetTop += el.offsetTop
        el = el.offsetParent
      }
      return offsetTop
    },
  }
}
</script>

<style lang="scss" scoped>
.tabs {
  display: flex;
  justify-content: center;
  margin: 100px 0;
  span {
    border: 1px solid red;
    margin-right: 10px;
    padding: 10px 20px;
    cursor: pointer;
  }
}
.tab_content {
  width: 60vw;
  height: 80vh;
  border: 1px solid red;
  margin: 10vh auto;
}
</style>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue实现锚点定位(多级动态菜单) 的相关文章