vue双向锚点实现过程简易版(scrollIntoView)

 更新时间:2024年07月24日 09:31:12   作者:Lemon今天学习了吗  
这篇文章主要介绍了vue双向锚点实现过程简易版(scrollIntoView),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、需求

左边是内容板块,右边是目录结构,点击右边内容跳转到左边相应位置展示,滑动左边内容右边目录自动跳转。

二、实现

  • 左边每一个内容模块都给一个ref和应该相同的class类名,方便获取dom;
  • 左边内容区域使用滑动事件@scroll="handleScroll",内容区域滑动即触发该方法;
  • 右边使用点击事件@click="goAnchor('anchor-' + index, index)"获取当前点击的dom;

  • handleScroll() 滚动监听方法实现滑动左边内容对应上右边目录

  • goAnchor() 右边锚点选中跳转相应内容区域,通过scrollIntoView({ behavior: 'smooth' })平滑跳转

实现代码

<template>
  <div class="panel-block flex">
    <div class="panel-left" ref="anchorRef" @scroll="handleScroll">
      <div class="panel-item anchor-item" ref="anchor-0">
        <div class="panel-item-title">内容区域1</div>
        xxx
      </div>
     <div class="panel-item anchor-item" ref="anchor-1">
        <div class="panel-item-title">内容区域2</div>
        xxx
      </div>
      <div class="panel-item anchor-item" ref="anchor-2">
        <div class="panel-item-title">内容区域3</div>
        <div class="panel-item-content">
         xxx
        </div>
      </div>
      <div class="panel-item anchor-item" ref="anchor-3">
        <div class="panel-item-title">内容区域4</div>
        <div class="panel-item-content">
         xxx
        </div>
      </div>
    </div>
    <div class="panel-right">
      <div class="step-line"></div>
      <ul class="step-ul">
        <li
          class="flex_align_item_center"
          v-for="(item, index) in stepData"
          :key="index"
          :class="{ 'step-active': activeBtn == index }"
          @click="goAnchor('anchor-' + index, index)"
        >
          <div class="step-icon"></div>
          <div class="step-label">{{ item }}</div>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      activeBtn: 0, //锚点按钮
      stepData: ['区域1', '区域2', '区域3', '区域4'],
      contentDiv: null, //锚点区域
    }
  },
  methods: {
    //锚点跳转
    goAnchor(selector, index) {
      this.activeBtn = index
      this.$refs[selector].scrollIntoView({ behavior: 'smooth' })
    },
    // 滚动监听器
    handleScroll(i) {
      // 获取所有锚点元素
      const navContents = document.querySelectorAll('.anchor-item')
      // 所有锚点元素的 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>
-----------------以下为样式代码----------------------
<style lang="scss" scoped>
.panel-block {
    height: 100%;
    .panel-left {
      width: calc(100% - 180px);
      overflow-y: auto;
      height: 100%;
      .panel-item {
        .panel-item-content {
          padding: 10px;
          border-top: 0;
          min-height: 40px;
          .table-params {
            .table-header {
              height: 40px;
              line-height: 40px;
              width: 100%;
              border: 1px solid #ebeef5;
              border-bottom: none;
              background: #f5f7fa;
              font-weight: 700;
              font-size: 14px;
              color: #303133;
              padding-left: 15px;
            }
            .table-body-type {
              height: 32px;
              line-height: 32px;
              width: 100%;
              border: 1px solid #ebeef5;
              border-bottom: none;
              color: #303133;
              padding-left: 15px;
              .type-title {
                font-weight: 700;
                font-size: 12px;
              }
            }
          }
        }
      }
    }
    .panel-right {
      padding-top: 10px;
      position: fixed;
      left: calc(100% - 210px);
      .step-line {
        position: absolute;
        left: 6px;
        top: 0;
        width: 1px;
        background: #dcdfe6;
        height: calc(50vh - 85px);
        z-index: 0;
      }
      .step-ul {
        li {
          padding-bottom: 20px;
          .step-icon {
            width: 13px;
            height: 13px;
            margin-right: 20px;
            border-radius: 50%;
            z-index: 1;
          }
          .step-label {
            font-weight: 700;
            font-size: 14px;
            line-height: 22px;
            color: #303133;
          }
        }
        .step-active {
          .step-icon {
            border: 1px solid #1989fe;
            background: #fff;
          }
          .step-label {
            color: #1989fe;
          }
        }
      }
    }
    ::-webkit-scrollbar {
      width: 0 !important;
    }
  }
</style>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue引入jq插件的实例讲解

    vue引入jq插件的实例讲解

    下面小编就为大家带来一篇vue引入jq插件的实例讲解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Vue3 如何通过虚拟DOM更新页面详解

    Vue3 如何通过虚拟DOM更新页面详解

    这篇文章主要为大家介绍了Vue3 如何通过虚拟DOM更新页面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 对vue中的input输入框进行邮箱验证方式

    对vue中的input输入框进行邮箱验证方式

    这篇文章主要介绍了对vue中的input输入框进行邮箱验证方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 简单实现Vue的observer和watcher

    简单实现Vue的observer和watcher

    这篇文章主要教大家如何简单实现Vue的observer和watcher,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • electron+vue3实现自动更新的示例代码

    electron+vue3实现自动更新的示例代码

    本文主要介绍了electron+vue3实现自动更新的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-10-10
  • 详解Vue3.0中ElementPlus<input输入框自动获取焦点>

    详解Vue3.0中ElementPlus<input输入框自动获取焦点>

    这篇文章主要给大家介绍了关于Vue3.0中ElementPlus<input输入框自动获取焦点>的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用vue3.0具有一定的参考学习价值,需要的朋友可以参考下
    2023-04-04
  • vue3如何使用provide实现状态管理详解

    vue3如何使用provide实现状态管理详解

    Vue3中有一对新增的api,provide和inject,熟悉Vue2的朋友应该明,这篇文章主要给大家介绍了关于vue3如何使用provide实现状态管理的相关资料,需要的朋友可以参考下
    2021-10-10
  • Vue实现滚动加载更多效果的示例代码

    Vue实现滚动加载更多效果的示例代码

    这篇文章介绍了在 Web 应用中处理大量数据展示的两种滚动加载更多方案,滚动加载更多通过分页工作,优点是实现简单、用户体验流畅,缺点是内存占用可能过高,虚拟列表只渲染视口内容,性能好但实现复杂,本文介绍了Vue实现滚动加载更多效果,需要的朋友可以参考下
    2024-12-12
  • vue3获取当前路由地址的两种方法

    vue3获取当前路由地址的两种方法

    近期在做ve3的项目时因为功能需要,需要获取当前路由的地址,下面这篇文章主要给大家介绍了关于vue3获取当前路由地址的两种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • 使用kbone解决Vue项目同时支持小程序问题

    使用kbone解决Vue项目同时支持小程序问题

    这篇文章主要介绍了使用kbone解决Vue项目同时支持小程序问题,本文通过一个todo的例子跟大家详细介绍,需要的朋友可以参考下
    2019-11-11

最新评论