实现思路
- 监听tab的点击事件,并滚动到对应的元素
- 监听滚动,并计算距离顶部最近的元素,将元素置为活跃状态
<header class="tab">
<span
v-for="(tab, index) in TABS"
:key="tab.id"
@click="scrollToPosition(tab.id)"
:class="{ active: currentIndex === index }"
>
{{ tab.label }}
</span>
</header>
<main
class="content-container"
@scroll="onScroll"
ref="contentContainerRef"
>
<div
id="statistics"
class="content-item"
/>
<div
id="display"
class="content-item"
/>
</main>
<script>
const TABS = [
{ label: '统计', id: 'statistics' },
{ label: '展示', id: 'display' }
]
const currentIndex = ref(0)
const onScroll = () => {
const sections = document.querySelectorAll('.content-item')
let closestIndex = 0
let minDistance = Infinity
const scrollTop = contentContainerRef.value.scrollTop
sections.forEach((section, index) => {
const distanceFromTop = Math.abs((section as any).offsetTop - scrollTop)
if (distanceFromTop < minDistance) {
minDistance = distanceFromTop
closestIndex = index
}
})
if (closestIndex !== currentIndex.value) {
currentIndex.value = closestIndex
}
}
const scrollToPosition = (id: string) => {
const el = document.getElementById(id)
if (el) el.scrollIntoView({ behavior: 'smooth' })
}
</script>