vue实现左右楼层跳转

实现思路
通过监听滚动事件获取当前滚动位置,与预设的楼层位置进行对比,确定当前所在楼层。点击右侧导航栏时,平滑滚动到对应楼层。
HTML结构
<template>
<div class="container">
<!-- 左侧内容区 -->
<div class="content" ref="content">
<div v-for="(item, index) in floors" :key="index" :id="`floor-${index}`" class="floor">
<h2>{{ item.title }}</h2>
<p>{{ item.content }}</p>
</div>
</div>
<!-- 右侧导航栏 -->
<div class="nav">
<ul>
<li
v-for="(item, index) in floors"
:key="index"
:class="{ active: currentFloor === index }"
@click="scrollTo(index)"
>
{{ item.title }}
</li>
</ul>
</div>
</div>
</template>
JavaScript逻辑
<script>
export default {
data() {
return {
floors: [
{ title: '楼层1', content: '内容1...' },
{ title: '楼层2', content: '内容2...' },
{ title: '楼层3', content: '内容3...' }
],
currentFloor: 0,
floorPositions: []
}
},
mounted() {
this.calculatePositions()
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
},
methods: {
calculatePositions() {
this.floorPositions = this.floors.map((_, index) => {
const el = document.getElementById(`floor-${index}`)
return el.offsetTop
})
},
handleScroll() {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
this.floorPositions.forEach((pos, index) => {
if (scrollTop >= pos - 100) {
this.currentFloor = index
}
})
},
scrollTo(index) {
const target = this.floorPositions[index]
window.scrollTo({
top: target,
behavior: 'smooth'
})
}
}
}
</script>
CSS样式
<style scoped>
.container {
display: flex;
}
.content {
flex: 1;
}
.floor {
height: 100vh;
padding: 20px;
border-bottom: 1px solid #eee;
}
.nav {
width: 200px;
position: fixed;
right: 0;
top: 50%;
transform: translateY(-50%);
}
.nav li {
padding: 10px;
cursor: pointer;
}
.nav li.active {
color: red;
font-weight: bold;
}
</style>
关键点说明
楼层位置计算在mounted钩子中完成,通过获取每个楼层元素的offsetTop值存储到数组。滚动事件监听实时比较滚动位置与楼层位置,更新当前楼层索引。点击导航时使用scrollTo方法实现平滑滚动。
优化建议
添加防抖处理减少scroll事件触发频率,提升性能。对于动态内容,可在内容变化后调用calculatePositions重新计算位置。考虑使用Intersection Observer API替代scroll事件监听,实现更高效的楼层检测。







