当前位置 : 主页 > 网络编程 > JavaScript >

vue实现锚点跳转之scrollIntoView()方法详解

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 vue锚点跳转scrollIntoView()方法 滚动到某个特定元素 一个简单的vue锚点跳转demo vue锚点跳转scrollIntoView()方法 滚动到某个特定元素 scrollIntoView();这个方法不用获取右边小标题的高度,
目录
  • vue锚点跳转scrollIntoView()方法
    • 滚动到某个特定元素 
  • 一个简单的vue锚点跳转demo

    vue锚点跳转scrollIntoView()方法

    滚动到某个特定元素 

    scrollIntoView();这个方法不用获取右边小标题的高度,啥都不用,有id或者class就行啦,几乎可以满足你锚点跳转的所有需求,对齐方式,以及平滑滚动了

    这里是v-for循环出来需要点击跳转到对应div的事件

    <p> v-for="(value,index) in data" @click="scrollToPosition(index)">{{...}}</p>  

    这就是你点击scrollToPosition事件需要滚动对应的div

    <div> v-for="(value,index) in data" class="roll">{{...}}</div>  

    js部分

    methods:{
      scrollToPosition(index){
         document.getElementsByClassName('roll')[index].scrollIntoView()
    }

    这样就利用scrollIntoView()简单实现了一个锚点跳转,下边来看一个scrollIntoView中的一些属性

    • scrollIntoView(true)相等于scrollIntoView();元素的顶端将和其所在滚动区的可视区域的顶端对齐

    为true时相应的 scrollIntoViewOptions: {block: “start”, inline: “nearest”}。这是这个参数的默认值。

    • scrollIntoView(false)元素的底端将和其所在滚动区的可视区域的底端对齐

    为false时相应的scrollIntoViewOptions: {block: “end”, inline: “nearest”}。

    同时他的参数也可以是一个object对象

      scrollIntoView({
      behavior:auto //定义动画过渡效果"auto"或 "smooth" 之一。默认为 "auto"。
      block:start//定义垂直方向的对齐, "start", "center", "end", 或 "nearest"之一。默认为 "start"。
      inline:nearest//"start", "center", "end", 或 "nearest"之一。默认为 "nearest"。
      })

    其中smooth是平滑滚动 start和end是目标滚动到的位置

    注意:

    兼容性的问题多数主流浏览器已经支持其基本功能,也就是说,使用true,false两个参数,来实现木讷的定位(没有滚动动画)是没有任何问题的,但是传入object参数时,就不得不说一句,IE各种版本会直接忽略,全部看成true参数属性,如果想看到滚动动画,就只有火狐和chrome 

    一个简单的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>
    

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

    上一篇:vue3中defineComponent 的作用详解
    下一篇:没有了
    网友评论