html代码
<template>
<div class="linkage">
<div class="linkage-button" ref="linkage-button">
<div class="linkage-button-list" ref="linkage-button-list">
<div
:class="
index == ButtonListIndex
? 'linkage-button-item ac'
: 'linkage-button-item'
"
v-for="(item, index) in ButtonList"
:key="item.id"
@click="FnButtonTab(index)"
>
{{ item.text }}
</div>
</div>
</div>
<div class="linkage-content" ref="linkage-content" @scroll="FnScroll">
<div class="linkage-content-list">
<div
class="linkage-content-item"
v-for="item in ContentList"
:key="item.id"
:style="{ height: `${item.height}px` }"
>
<div class="linkage-content-title">{{ item.text }}</div>
</div>
</div>
</div>
</div>
</template>
js代码
<script>
export default {
name: "linkage",
data() {
return {
ButtonList: [],
ContentList: [],
ButtonListIndex: 0,
ScrollBys: true,
};
},
methods: {
// 左侧按钮的渲染
FnSetButton(n) {
for (var i = 0; i < n; i++) {
this.ButtonList.push({
id: `按钮${i}`,
text: `按钮${i}`,
});
}
},
// 右侧内容的渲染
FnSetContent(n) {
let ContTop = 0; //第一个元素距离页面顶部的距离
let Random = this.FnSetRandom(750, 1400);
for (let i = 0; i < n; i++) {
this.ContentList.push({
height: Random,
id: `内容${i}`,
text: `内容${i}`,
top: ContTop,
});
ContTop += Random;
}
},
// 随机数
FnSetRandom(m, n) {
return parseInt(Math.random() * (m - n) + n);
},
// 点击切换左边
FnButtonTab(index) {
this.ScrollBys = false;
this.ButtonListIndex = index;
this.$refs["linkage-content"].scrollTop = this.ContentList[index].top;
},
// 右边滚动切换左边
FnScroll(ev) {
this.ContTop = ev.target.scrollTop;
if (this.ScrollBys) {
let n = 0;
for (let i = 0; i < this.ContentList.length; i++) {
if (
this.$refs["linkage-content"].scrollTop >= this.ContentList[i].top
) {
//盒子滚动的距离如果大于右边盒子里的元素距离页面顶部的距离
n = i;
}
}
this.ButtonListIndex = n;
}
if (this.ContTop == this.ContentList[this.ButtonListIndex].top) {
this.ScrollBys = true;
}
},
},
mounted() {
this.ButtonHeight =
this.$refs["linkage-button-list"].children[0].offsetHeight;
this.centerIndex = Math.floor(
( this.$refs["linkage-button"].offsetHeight / this.ButtonHeight )/2
);
// console.log(this.centerIndex)
},
created() {
this.FnSetButton(20);
this.FnSetContent(20);
},
watch: {
ButtonListIndex(index) {
if (index > this.centerIndex) {
this.$refs["linkage-button"].scrollTop =
(index - this.centerIndex) * this.ButtonHeight;
}
if (index < this.centerIndex) {
this.$refs["linkage-button"].scrollTop = 0;
}
},
},
};
</script>
css代码
<style lang="less" scoped>
body {
margin: 0;
}
.linkage {
width: 100vw;
height: 100vh;
display: flex;
.linkage-button {
width: 20vw;
height: 100vh;
background: chocolate;
text-align: center;
font-size: 40px;
color: #fff;
overflow: scroll;
scroll-behavior: smooth;
.linkage-button-list {
width: 20vw;
.linkage-button-item.ac {
background: lightblue;
}
.linkage-button-item {
width: 20vw;
height: 10vh;
line-height: 10vh;
}
}
}
.linkage-content {
width: 80vw;
height: 100vh;
scroll-behavior: smooth;
overflow: scroll;
.linkage-content-list {
.linkage-content-item {
width: 80vw;
height: 100vh;
.linkage-content-title {
height: 6vh;
line-height: 6vh;
width: 80vw;
text-align: center;
background: chartreuse;
color: #fff;
font-size: 30px;
}
}
}
}
}
.linkage-button::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
.linkage-content::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
</style>