点击导航栏滚动到对应位置并且滚动到对应位置时高亮对应的导航

5 阅读1分钟

实现思路

  • 监听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>