一. 页面样式
二. 代码
<div class="flexBox"><div class="mdDiv" v-for="(item,index) in tabList" :key="index" :class="nowChoose==index?'choosed':''" @click="jumpMD(index, item.id)">{{item.name}}</div>
</div>
<div class="mainDiv" @scroll="onscroll"><div id="intro">课程简介</div><div id="bright">课程简介</div><div id="formAndTime">培训形式与时间</div><div id="content">课程内容</div>
</div>
import { ref, nextTick } from "vue"
nextTick(() =>{getTop() // 在nextTick中获取dom元素
})
const tabList = ref([{ name: "课程简介",id:"intro" },{ name: "课程亮点",id:"bright" },{ name: "培训形式与时间",id:"formAndTime" },{ name: "课程内容",id:"content" },])const nowChoose = ref(0)
const isTap = ref(false) // 是否为点击滑动
const jumpMD = (index, id) =>{isTap.value = true // 点击滑动 下标直接变nowChoose.value= indexdocument.getElementById(id).scrollIntoView({behavior: "smooth"})setTimeout(() =>{isTap.value = false }, 300)
}
const scrollList = [] // 几个锚点距离父顶部的距离
const getTop = () =>{ // 获取锚点div到父级的距离scrollList.value = []tabList.value.forEach(item =>{scrollList.value.push(document.getElementById(item.id).offsetTop)})
}
const onscroll = (e) =>{ // 监听页面滚动if (!isTap.value) { // 非点击滑动走这里if (scrollList.value.length) {scrollList.value.forEach((item, index) =>{if (e.target.scrollTop + 60 > item) {nowChoose.value = index}})}}}
三. 易错点讲解
1. 获取子元素到父元素最上方的高
document.getElementById(item.id).offsetTop
在父元素上一定要加
position: relative;
否则就获取到页面顶部的距离了
2. 点击滚动 跟 滚动切换要区分开
监听滚动的事件是一直触发的 我们点击的时候就判断一下 不走滚动里的 当然 滚动也不走监听里的 不然会鬼畜哦