官网:scrollintoView
通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视窗中。
利用scrollIntoView() 函数 默认是true
document.getElementById(需要滚动的div的id).scrollIntoView()
如果给该方法传入true作为参数,或者不传入任何参数,那么 窗口滚动之后会让调动元素顶部和视窗顶部尽可能齐平。
如果给该方法传入false作为参数,调用元素会尽可能全部出现在视口中(可能的话,调用元素的底部会与视口的顶部齐平)不过顶部不一定齐平。
代码实现
// vue
<template>
<div class="panelBlock flex">
<div class="panelLeft" ref="anchorRef" @scroll="handleScroll">
<div class="panelItem anchorItem" ref="anchor0">
<div class="panelItemTitle">内容标题1</div>
<div class='panelItemContent'>
描述描述描述描述描述描述描述
</div>
</div>
<div class="panelItem anchorItem" ref="anchor1">
<div class="panelItemTitle">内容标题2</div>
xxx
</div>
<div class="panelItem anchorItem" ref="anchor2">
<div class="ppanelItemTitle">内容标题3</div>
<div class="panelItemContent">
描述描述描述描述描述描述描述
</div>
</div>
<div class="panelItem anchorItem" ref="anchor3">
<div class="panelItemTitle">内容标题4</div>
<div class="panelItemContent">
描述描述描述描述描述描述描述
</div>
</div>
</div>
<div class="panelRight">
<div class="stepLine"></div>
<ul>
<li
v-for="(item, index) in stepData"
:key="index"
:class="{ 'stepActive': activeBtn == index }"
@click="goAnchor('anchor' + index, index)"
>
<div class="stepIcon"></div>
<div class="stepLabel">{{ item }}</div>
</li>
</ul>
</div>
</div>
</template>
<script>
// js
export default {
data() {
return {
activeBtn: 0, //锚点按钮
stepData: ['标题1', '标题2', '标题3', '标题4'],
}
},
methods: {
//锚点跳转
goAnchor(dom, index) {
this.activeBtn = index
this.$refs[dom][0].scrollIntoView({ behavior: 'smooth' })
},
// 滚动监听器
handleScroll() {
// 获取所有锚点元素
const navContents = document.querySelectorAll('.anchorItem')
// 所有锚点元素的 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>
// css
<style lang="less">
.panelBlock{
height: 100%;
.panelLeft {
width: calc(100% - 180px);
overflow-y: auto;
height: 100%;
. panelItem{
.panelItemContent {
padding: 10px;
border-top: 0;
min-height: 40px;
}
}
}
}
.panelRight {
padding-top: 10px;
position: fixed;
left: calc(100% - 210px);
.stepLine {
position: absolute;
left: 6px;
top: 0;
width: 1px;
background: #dcdfe6;
height: calc(50vh - 85px);
z-index: 0;
}
ul {
li {
padding-bottom: 20px;
.stepIcon {
width: 13px;
height: 13px;
margin-right: 20px;
border-radius: 50%;
z-index: 1;
}
.stepLabel {
font-weight: 700;
font-size: 14px;
line-height: 22px;
color: #303133;
}
}
.stepActive {
.stepIcon{
border: 1px solid #1989fe;
background: #fff;
}
.stepLabel {
color: #1989fe;
}
}
}
}
}
</style>
可能报错
this. r e f s . i t e m 1. s c r o l l I n t o V i e w i s n o t a f u n c t i o n , t h i s . refs.item1.scrollIntoView is not a function,this. refs.item1.scrollIntoViewisnotafunction,this.refs[dom].scrollIntoView is not a function
原因
获取的ref是一个数组,故而获取不到对应方法
修改
// 原代码
this.$refs[dom].scrollIntoView({behavior:'smooth'})
// 修改后代码
this.$refs[dom][0].scrollIntoView({behavior:'smooth'})