el-steps步骤条结合锚点实现页面滚动定位

el-steps步骤条结合锚点实现页面滚动定位

需求描述:给页面加个导航定位条,页面滚动到某个模块时,右侧步骤条跟着滚动,相反之,点击导航步骤条的某个模块,页面可定位到相应模块

实现效果如图:(因为公司项目不便于录制gif视频)
在这里插入图片描述

element中的步骤条没有任何点击事件,只是起到一个展示的作用,由于其它页面也有用到,便封装成了一个公共的组件
在这里插入图片描述
step中的代码:

<template>
  <div class="step">
    <div style="height: 180px; position: relative">
      <el-steps direction="vertical" :active="current">
        <el-step
          :title="item.stepTitle"
          v-for="(item, index) in stepInfo"
          :key="index"
          icon="el-icon-success"
        >
        </el-step>
      </el-steps>
      <!-- steps绑定不上任何点击事件,给了相应数据的span便签覆盖上,可以绑定点击事件 -->
      <span
        class="stepIndex"
        v-for="(itemId, indexID) in stepInfo"
        :key="itemId.stepId"
        @click="jumpPage(itemId.stepId)"
        :class="'step' + indexID"
      ></span>
    </div>
  </div>
</template>

<script>
import { mount } from "@vue/test-utils";
export default {
  name: "common-step",
  props: {
    // stepInfo是每一个步骤的信息,格式如下(stepID是每个模块的类名以便获取dom)
    //  stepInfo: [
    //     {
    //       stepTitle: "基本信息",
    //       stepId: "baseinfo",
    //     },
    //     {
    //       stepTitle: "配置规则",
    //       stepId: "ruleinfo",
    //     },
    //     {
    //       stepTitle: "生成任务列表",
    //       stepId: "taskinfo",
    //     },
    //   ],
    stepInfo: {
      type: Array,
      default: () => [],
    },
    // 当前步骤条的滚动位置
    current: {
      type: Number,
      default: () => 1
    }
  },
  data () {
    return {
    };
  },

  methods: {
    jumpPage (domId) {
      // 当前窗口正中心位置到指定dom位置的距离
      //页面滚动了的距离
      let height =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;
      //指定dom到页面顶端的距离
      let dom = document.getElementById(domId);
      let domHeight = dom.offsetTop;
      //   //滚动距离计算
      let distance = Number(height) - Number(domHeight);
      //   //判断上滚还是下滚
      if (distance < 0) {
        //向下滚动
        distance = Math.abs(distance);
        this.$emit("scrollBy", { top: distance, behavior: 'smooth' });
      } else if (distance == 0) {
        //页面不滚动
        this.$emit("scrollBy", { top: 0, behavior: 'smooth' });
      } else {
        //向上滚动
        distance = -distance;
        this.$emit("scrollBy", { top: distance, behavior: 'smooth' });
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.step {
  position: fixed;
  right: 3%;
  font-size: 14px;
}
.stepIndex {
  position: absolute;
  z-index: 3;
  width: 100%;
  height: 28px;
}
.step0 {
  top: 0;
}
.step1 {
  top: 76px;
}
.step2 {
  top: 152px;
}
::v-deep .el-step__head.is-wait {
  color: #303133;
  border-color: #303133;
}
::v-deep .el-step__title.is-wait {
  color: #303133;
  font-weight: bold;
  font-size: 14px;
}
::v-deep .is-process,
::v-deep .is-finish {
  font-size: 14px;
}
::v-deep .el-icon-success {
  font-size: 16px !important;
}
</style>

父组件中使用

在这里插入图片描述
这里的current是控制步骤条滚动的,我放到了父组件里面,因为我这里要监听到父组件页面的滚动任何实现current的增减

父组件里面mounted和beforedestroyed中监听滚动

mounted () {
    // 获取滚动部分的dom元素
    const dom_html = this.$refs.scrolldom.$refs.wrap;
    dom_html.addEventListener("scroll", this.getScrollId);
  },
  beforedestroyed () {
    const dom_html = this.$refs.scrolldom.$refs.wrap;
    dom_html.removeEventListener("scroll", this.getScrollId);
  },
// dom滚动监听事件
    getScrollId () {
      this.current = 0;
      const dom_one = document.getElementById("baseinfo").offsetTop;
      const dom_two = document.getElementById("ruleinfo").offsetTop;
      const dom_three = document.getElementById("taskinfo").offsetTop;
      const sroll_top = this.$refs.scrolldom.$refs.wrap.scrollTop;
      //目前导航只有三个,就用了最笨的if判断来写了
      if (sroll_top < dom_two) {
        this.current = 1;
      } else if (sroll_top === dom_two || sroll_top < dom_three) {
        this.current = 2;
      } else {
        this.current = 3;
      }
    },
 // 获取步骤条点击事件定位到相应模块
    scrollBy (params) {
      const dom_html = this.$refs.scrolldom.$refs.wrap;
      this.$nextTick(() => {
        dom_html.scrollTop = params.top;
      });
    },

至此效果已经实现了

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
HTML中实现锚点定位并具有滚动效果的方法有多种。一种常见的方法是使用CSS的scroll-behavior属性和a标签的href属性。首先,在CSS中设置scroll-behavior属性为smooth,这将使得滚动滚动时具有平滑的效果。然后,在a标签中的href属性中设置目标位置的id值,例如#section。当点击该链接时,页面将会平滑滚动到相应的目标位置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [HTML锚点定位+平滑滚动](https://blog.csdn.net/m0_64520392/article/details/128941349)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [微信小程序-scroll-view滚动到指定位置(类似锚点)](https://download.csdn.net/download/weixin_38601878/16213063)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [vue+导航锚点联动-滚动监听和点击平滑滚动跳转实例](https://download.csdn.net/download/weixin_38665822/13982520)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值