1.给页面添加滚动监听
window.addEventListener("scroll", this.handleScroll);
//this.handleScroll 滚动时会触发的方法
2.创建handleScroll方法
3.在页面最下方添加一个div,用于判断页面是否到了底部
<div
class="seefooter"
ref="seefooter"
style="height: 10px; background-color: transparent"
></div>
4.监测这个div的位置
handleScroll() {
const seefooter = this.$refs.seefooter;
if (seefooter.getBoundingClientRect().bottom < window.innerHeight) {
console.log("触底");
return;//阻止后面的事件继续执行,不然会有问题
}
},
//监测条件如果不适合可以自行调整
5.获取需要监测的元素,可根据实际情况调整,这里的是根据数据循环出来的,循环数据从而选中每个元素-记得给这些元素加上相应的ref
<!-- 类似这样的 -->
<div v-for="item in listData" :key="item.id" :ref="`content-box${item.id}`">{{ item.name }}</div>
数据长这样:
listData: [
{
id: "1",
name: "菜单1",
},
{
id: "2",
name: "菜单2",
},
],
获取元素
this.listData.forEach((item) => {
const content = this.$refs[`content-box${item.id}`];//循环获取
});
6.获取到之后就需要监测每个元素了
this.listData.forEach((item) => {
const content = this.$refs[`content-box${item.id}`]; //循环获取
if (content) {
const rect = content[0].getBoundingClientRect();
if (rect.top <= 100 && rect.top >= -10) { //判断是否在可视范围内,这个可视范围可以自行调整
console.log("到" + item.id + "高亮了");
// 可以在这去改变菜单的高亮
}
}
});
7.监测到满足条件的元素根据关联关系去修改菜单的高亮。
方法大致的代码大概就长这个样子了:
handleScroll() {
const seefooter = this.$refs.seefooter;
if (seefooter.getBoundingClientRect().bottom < window.innerHeight) {
console.log("触底");
return; //阻止后面的事件继续执行,不然会有问题
}
this.listData.forEach((item) => {
const content = this.$refs[`content-box${item.id}`]; //循环获取
if (content) {
const rect = content[0].getBoundingClientRect();
if (rect.top <= 100 && rect.top >= -10) {
//判断是否在可视范围内,这个可视范围可以自行调整
console.log("到" + item.id + "高亮了");
// 可以在这去改变菜单的高亮
}
}
});
,
8.准备点击菜单滑动到指定元素那里(还有点问题,如果不满足还需另行寻找方法)
9.切记点击之后在执行滚动方法之前一定要取消页面的滚动监听,结束之后再加上,或者执行其他操作时加上,不取消掉会有冲突
代码如下
toScroll(newval) {
new Promise((resolve) => {
setTimeout(() => {
this.$nextTick(() => {
try {
// 移除window滚动事件
window.removeEventListener("scroll", this.handleScroll);
// 首次进入会获取不到元素
this.$refs[`content-box${newval}`][0].scrollIntoView({
behavior: "smooth",
block: "center",
});
this.scrollId = "";
} catch (error) {
this.scrollId = newval;
}
});
resolve();
}, 100);
}).then(() => {
setTimeout(() => {
window.addEventListener("scroll", this.handleScroll);
}, 500);
});
},
以上只是一种思路,还有bug,但是能力有限只能想到这了