vue项目使用锚点双向定位滚动功能
如图所示: 点击左侧菜单可以跳转到对应内容,鼠标滚轮滚动时菜单也根据内容显示active项 代码如下:
给父盒子一个id
<div class="case-infos" id="content">
<ul class="tabs">
<li
v-for="(item, index) in tabsList"
:key="index"
:class="{ active: index === activeIndex }"
@click.stop="toContent(item, index)"
>
{{ item.name }}
</li>
</ul>
<div class="case-content">
<div
v-for="(item, index) in tabsList"
:key="index"
:id="`content-item${index}`"
>
<div class="content-name">{{ item.name }}</div>
<div
class="content-info"
v-html="caseDetail.introduction"
></div>
</div>
</div>
</div>
css代码 注意要给父盒子设置overflow 菜单栏设置固定定位 一定要加一定要加一定要加overflow
.case-infos {
min-height: 500px;
overflow-y: auto;
max-height: 800px;
position: relative;
.tabs {
position: fixed;
right: calc(50% - 573px);
top: 320px;
}
.case-content {
position: relative;
}
}
js代码
data(){
return{
tabsList: [],
activeIndex: 0,
contentLocation: [],
}
}
created(){
this.getCourseCasesDetail()
},
mounted() {
this.$nextTick(function () {
this.addScrollFun()
})
},
methods: {
toContent(item, index) {
this.$nextTick(() => {
this.removeScrollFun()
this.activeIndex = index
document.querySelector('#content').scroll({
top: document.querySelector(`#content-item${index}`).offsetTop,
behavior: 'auto',
})
this.addScrollFun()
})
},
addScrollFun() {
document
.querySelector('#content')
.addEventListener('scroll', this.listenScroll)
},
removeScrollFun() {
document
.querySelector('#content')
.removeEventListener('scroll', this.listenScroll)
},
listenScroll(e) {
this.contentLocation.forEach((el, index) => {
if (e.target.scrollTop >= el - 34) {
this.activeIndex = index
}
})
},
handleLocation() {
this.contentLocation = []
if (Array.isArray(this.tabsList)) {
this.tabsList.forEach((ele, index) => {
this.contentLocation.push(
document.querySelector(`#content-item${index}`).offsetTop
)
})
}
},
getCourseCasesDetail() {
this.$api.getCourseCasesDetail({
casesId: this.$route.query.id,
})
.then((response) => {
this.caseDetail = response.data
this.$nextTick(() => {
this.handleLocation()
})
})
.catch((error) => {
console.log('getCourseCasesDetail error: ', error)
})
},
}
代码部大概就是这么多。但是还有个小问题就是最后一个内容如果太少,会有点不对劲,待解决,或者下次找更好的办法
|