一个简单的vue锚点跳转demo

一个简单的vue锚点跳转demo

拿去直接粘贴就可

<template>
  <div class="auto-adjust-edit" >
    <!-- 按钮 -->
    <div class="operation-btn">
        <div class="btn-item" v-for="(item, index) in partList" :key="index" @click="jump(index)"
            :style="{background: activeStep === index ? '#eeeeee' : '#ffffff'}">{{item}}
        </div>
    </div>
    <!-- 滚动区域 -->
    <div class="scroll-content" @scroll="onScroll">
      <div class="scroll-item">
          <div class="part-title">基本信息</div>
      </div>
      <div class="scroll-item">
          <div class="part-title">风险控制</div>
      </div>
      <div class="scroll-item">
          <div class="part-title">成本控制</div>
      </div>
      <div class="scroll-item">
          <div class="part-title">量级控制</div>
      </div>
      <div class="scroll-item">
          <div class="part-title">新计划管理</div>
      </div>
      <div class="scroll-item">
          <div class="part-title">老计划管理</div>
      </div>
      <div class="scroll-item">
          <div class="part-title">垃圾计划清理</div>
      </div>
    </div>
    
  </div>
</template>
<script>
export default {
    data() {
        return {
            activeStep: 0,
            partList: ['基本信息', '风险控制', '成本控制', '量级控制', '新计划管理', '老计划管理', '垃圾计划清理']
        }
    },
    methods: {
        // 滚动触发按钮高亮
        onScroll (e) {
            let scrollItems = document.querySelectorAll('.scroll-item')
            for (let i = scrollItems.length - 1; i >= 0; i--) {
                // 判断滚动条滚动距离是否大于当前滚动项可滚动距离
                let judge = e.target.scrollTop >= scrollItems[i].offsetTop - scrollItems[0].offsetTop - 100;
                if (judge) {
                    this.activeStep = i
                    break
                }
            }
        },
        // 点击切换锚点
        jump (index) {
            let target = document.querySelector('.scroll-content')
            let scrollItems = document.querySelectorAll('.scroll-item')
            // 判断滚动条是否滚动到底部
            if (target.scrollHeight <= target.scrollTop + target.clientHeight) {
                this.activeStep = index
            }
            let total = scrollItems[index].offsetTop - scrollItems[0].offsetTop // 锚点元素距离其offsetParent(这里是body)顶部的距离(待滚动的距离)
            let distance = document.querySelector('.scroll-content').scrollTop // 滚动条距离滚动区域顶部的距离
            // let distance = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset // 滚动条距离滚动区域顶部的距离(滚动区域为窗口)
            // 滚动动画实现, 使用setTimeout的递归实现平滑滚动,将距离细分为50小段,10ms滚动一次
            // 计算每一小段的距离
            let step = total / 50
            if (total > distance) {
                smoothDown(document.querySelector('.scroll-content'))
            } else {
                let newTotal = distance - total
                step = newTotal / 50
                smoothUp(document.querySelector('.scroll-content'))
            }

            // 参数element为滚动区域
            function smoothDown (element) {
                if (distance < total) {
                    distance += step
                    element.scrollTop = distance
                    setTimeout(smoothDown.bind(this, element), 1)
                } else {
                    element.scrollTop = total
                }
            }

            // 参数element为滚动区域
            function smoothUp (element) {
                if (distance > total) {
                    distance -= step
                    element.scrollTop = distance
                    setTimeout(smoothUp.bind(this, element), 1)
                } else {
                    element.scrollTop = total
                }
            }
            // document.querySelectorAll('.scroll-item').forEach((item, index1) => {
            //   if (index === index1) {
            //     item.scrollIntoView({
            //       block: 'start',
            //       behavior: 'smooth'
            //     })
            //   }
            // })
        }

    }
}
</script>
<style lang="scss" scoped>
  .auto-adjust-edit {
    flex-basis: 100%;
    display: flex;
    overflow: hidden;
    height: 500px;
    height: 100%;
    // 侧边栏
    .operation-btn {
        width: 9.5%;
        height: 95%;
        margin-right: 0.5%;
        padding-top: 1%;
        margin-top: 4px;
        background: white;
        border: 1px solid rgb(190, 188, 188);
        border-radius: 6px;
        box-shadow: 0 3px 12px 0 rgba(0, 0, 0, 0.2);
        .btn-item {
            height: 40px;
            line-height: 40px;
            padding-left: 20px;
            cursor: pointer;
        }
    }
    // 表单内容
    .scroll-content {
        height: 100%;
        width: 90%;
        overflow: auto;
        .scroll-item {
            background: white;
            border-radius: 8px;
            margin-bottom: 6px;
            border: 1px solid rgb(216, 214, 214);
            min-height: 300px;
            // 标题
            .part-title {
                height: 40px;
                line-height: 40px;
                font-weight: 600;
                padding-left: 10px;
            }
            // 表单
            /deep/.el-form {
                border: 1px solid rgb(190, 189, 189);
                width: 98%;
                margin: 10px auto 30px;
                border-radius: 6px;
                /deep/.el-form-item {
                margin-bottom: 12px;
                margin-top: 10px;
                }
            }
        }
    }
  }
</style>

Respect to:

https://blog.csdn.net/love__xyy/article/details/88047306?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduend~default-1-88047306.nonecase&utm_term=vue%E9%94%9A%E7%82%B9%E6%8F%92%E4%BB%B6&spm=1000.2123.3001.4430

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值