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>
以上为个人经验,希望能给大家一个参考,也希望大家多多支持阿兔在线工具。