最近开发的时候,遇到这么一个需求,锚点定位侧边栏,先上图
这个功能一开始看上去就觉得简单,不就是锚点定位嘛,上代码,但是需要注意一些小细节
data() {
return {
highLight: 0,
}
},
// 首先监听页面的滚动事件
mounted() {
window.addEventListener('scroll', this.onScroll, false)
},
methods: {
onScroll() {
const navContents = document.querySelectorAll('.name') // 获取所有需要需要锚点定位的DOM元素
const offsetTopArr = []
navContents.forEach(item => {
offsetTopArr.push(item.offsetTop) // 获取上面DOM元素距离顶部的距离
})
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop // 获取页面滚动了距离
let navIndex = 0
for (let n = 0; n < offsetTopArr.length; n++) {
if (scrollTop >= offsetTopArr[n] - 200) { // 下面介绍为啥-200
navIndex = n
}
}
this.highLight = navIndex
},
}
// 锚点定位会将对应的元素定位到页面顶部,由于本人当前页面的头部导航是fixed布局,当锚点在顶部时
// 锚点对应的元素就被导航遮挡住了,所以减去200,让我们锚点元素不被遮挡展示出来
上面的代码就实现了当页面滚动时,滚动不同的距离,其对应的导航会高亮,接下来是切换右侧导航时页面滚动到对应位置
methods: {
scrollTo(index) {
// 获取高亮导航对应的锚点定位元素的 offsetTop
let targetOffsetTop
if (index == 0) {
targetOffsetTop = this.$refs.oneBox1.offsetTop
} else if (index == 1) {
targetOffsetTop = this.$refs.oneBox2.offsetTop
} else if (index == 2) {
targetOffsetTop = this.$refs.oneBox3.offsetTop
} else if (index == 3) {
targetOffsetTop = this.$refs.oneBox4.offsetTop
} else if (index == 4) {
targetOffsetTop = this.$refs.oneBox5.offsetTop
}
// 获取当前页面的 offsetTop
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
if (scrollTop > targetOffsetTop) { 判断需要往上滚动还是往下滚动
smoothUp()
} else {
smoothDown()
}
const STEP = 50
function smoothDown() {
if (scrollTop < targetOffsetTop - 150) { // 下面介绍为啥-150
if (targetOffsetTop - scrollTop >= STEP) {
scrollTop += STEP
} else {
scrollTop = targetOffsetTop
}
// 给页面的滚动距离重新设置,然后调用方法是页面平滑滚动
document.body.scrollTop = scrollTop
document.documentElement.scrollTop = scrollTop
requestAnimationFrame(smoothDown)
}
}
// 由于上面我们-200的头部导航距离,所以这里我们需要减少一定的值,由于在该项目上一开始-200会导致定位有点怪异,-150却比较正常
function smoothUp() {
if (scrollTop > targetOffsetTop) {
if (scrollTop - targetOffsetTop >= STEP) {
scrollTop -= STEP
} else {
scrollTop = targetOffsetTop
}
document.body.scrollTop = scrollTop - 150
document.documentElement.scrollTop = scrollTop - 150
requestAnimationFrame(smoothUp)
}
}
}
}
就这样,我们可以实现头部不被遮挡且平滑滚动的锚点定位啦。最后指出一个小bug,当你刷新页面时,数据都被重置了,但页面滚动的距离会被保留,导致右侧导航高亮没有对应。所以,我们新增下面的方法
mounted() {
window.addEventListener('beforeunload', (e) => {
window.scroll({
top: 0,
left: 0,
behavior: 'smooth'
});
})
}
最后
感谢你的阅读~
如果你有任何的疑问欢迎您在后台私信,我们一同探讨学习!
如果觉得这篇文章对你有所帮助,点赞、在看是最大的支持!