<template>
<div class="sideBar">
<div class="side_wrap">
<div
class="side_item"
@click="handleClick(item, index)"
v-for="(item, index) in sideList"
:class="{ active: item.active }"
:key="index"
>
{{ item.text }}
</div>
</div>
<div class="side_content">
<div
class="content_item"
:id="`content${index}`"
v-for="(item, index) in contentList"
:key="index"
:style="{ background: item.color }"
>
{{ item.text }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
sideList: [
{
text: "side1"
},
{
text: "side2"
},
{
text: "side3"
},
{
text: "side4"
},
{
text: "side5"
},
{
text: "side6"
}
],
contentList: [
{
text: "content1",
color: "red"
},
{
text: "content2",
color: "yellow"
},
{
text: "content3",
color: "pink"
},
{
text: "content4",
color: "skyblue"
},
{
text: "content5",
color: "greenyellow"
},
{
text: "content6",
color: "blanchedalmond"
}
],
clicked: false
};
},
methods: {
// 侧边栏点击
handleClick(item, index) {
this.clicked = true;
this.resetSide();
this.$set(this.sideList[index], "active", true);
var element = document.getElementById(`content${index}`);
// 让id为content${index}的元素滚动到浏览器窗口的可视区域内
element.scrollIntoView();
},
// 重置侧边栏选中
resetSide() {
this.sideList.forEach((side, ind) => {
this.$set(this.sideList[ind], "active", false);
});
},
handleScroll() {
let scrollTop =
document.body.offsetTop || document.documentElement.scrollTop; // 获取滚动条位置
if (this.clicked) {
this.clicked = false;
return;
}
for (let i = 0; i < this.list.length; i++) {
//未达到标题最低高度时
// if (scrollTop < this.list[0].offsetTop) {
// break;
// }
//在标题区间中
//最后一个标题
if (i == this.list.length - 1) {
this.resetSide();
this.$set(this.sideList[i], "active", true);
break;
} else if (
scrollTop >= this.list[i].offsetTop &&
scrollTop < this.list[i + 1].offsetTop
) {
this.resetSide();
this.$set(this.sideList[i], "active", true);
break;
}
}
}
},
mounted() {
this.resetSide();
this.$set(this.sideList[0], "active", true);
// 获取每个大div的offsetTop
this.list = [];
this.contentList.forEach((item, ind) => {
let obj = {
offsetTop: document.querySelector(`#content${ind}`).offsetTop
};
this.list.push(obj);
});
// 监听滚动事件
window.addEventListener("scroll", this.handleScroll);
}
};
</script>
<style scoped>
.side_wrap {
width: 100px;
position: fixed;
right: 0;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
}
.side_item {
height: 30px;
}
.content_item {
height: 100vh;
width: 100vh;
}
.active {
background: pink;
}
</style>