<template>
<div class="linkage">
<div class="content-box">
<div class="nav" ref="nav">
<div
@click="fnNav(index, $event)"
v-for="(item, index) in btnList"
:key="item.id"
:class="now == index ? 'nav-list ac' : 'nav-list'"
>
{{ item.val }}
</div>
</div>
<div class="content" ref="content" @scroll="contentScroll">
<div class="content-list" v-for="(cont, index) in btnList" :key="index">
<div class="title">{{ cont.val }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
now: 0,
listBoxState: true, //点击导航栏时,暂时停止监听页面滚动
btnList: [
{
id: "btn0",
val: "推荐",
},
{
id: "btn1",
val: "折扣",
},
{
id: "btn2",
val: "暑期特惠",
},
{
id: "btn3",
val: "烤肉拌饭",
},
{
id: "btn4",
val: "脆皮鸡烤肉",
},
{
id: "btn5",
val: "特惠双拼",
},
{
id: "btn6",
val: "超值盖浇饭",
},
{
id: "btn7",
val: "炒饭/炒饼",
},
{
id: "btn8",
val: "风味小吃",
},
{
id: "btn9",
val: "营养面食",
},
{
id: "btn10",
val: "酒水饮料",
},
],
contList: [
{
id: "cont0",
val: "推荐",
},
{
id: "cont1",
val: "折扣",
},
{
id: "cont2",
val: "暑期特惠",
},
{
id: "cont3",
val: "烤肉拌饭",
},
{
id: "cont4",
val: "脆皮鸡烤肉",
},
{
id: "cont5",
val: "特惠双拼",
},
{
id: "cont6",
val: "超值盖浇饭",
},
{
id: "cont7",
val: "炒饭/炒饼",
},
{
id: "cont8",
val: "风味小吃",
},
{
id: "cont9",
val: "营养面食",
},
{
id: "cont10",
val: "酒水饮料",
},
],
};
},
methods: {
fnNav(index, ev) {
// 点击时不触发右边滚动监听
this.listBoxState = false;
// 把index赋值给now
this.now = index;
// 导航条
this.Nav = this.$refs["nav"];
// 导航条子元素
this.NList = this.Nav.children;
// 内容区域
this.Content = this.$refs["content"];
// 内容区域子元素
this.CList = this.Content.children;
// 内容区父元素
this.Parent = this.Content.parentNode;
// 判断导航条位置是否该调整
if (this.now <= 3) {
this.$refs["nav"].scrollTop -= 500;
}
if (this.now >= this.NList.length - 3) {
this.$refs["nav"].scrollTop += 500;
}
// 内容区滚动的高度=子元素可视区距离顶部高度
this.Content.scrollTop = this.CList[index].offsetTop;
// 去除默认事件
ev.preventDefault = ev.preventDefault();
},
contentScroll() {
// 内容区域滚动高度
this.scrollTop = this.$refs["content"].scrollTop;
// 内容区子元素
this.CList = this.$refs["content"].children;
if (this.listBoxState) {
// 循环内容区子元素
for (var i = 0; i < this.CList.length; i++) {
// 判断内容区域滚动高度大于当前子元素距离顶部高度就将当前值i赋给now
if (this.scrollTop >= this.CList[i].offsetTop) {
this.now = i;
}
}
// 判断导航条位置是否该调整
if (this.now <= 3) {
this.$refs["nav"].scrollTop -= 500;
}
if (this.now >= this.NList.length - 3) {
this.$refs["nav"].scrollTop += 500;
}
}
// 打开左右联动
if (this.scrollTop == this.CList[this.now].offsetTop) {
this.listBoxState = true;
}
},
//随机数
getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
},
mounted() {
// 监听滚动
window.addEventListener("scroll", this.documentScroll);
this.NList = this.$refs["nav"].children;
// 内容区域子元素
this.CList = this.$refs["content"].children;
// 循环内容区子元素,并设置随机高度
for (var i = 0; i < this.CList.length; i++) {
this.CList[i].style.height = this.getRandom(150, 300) + "vh";
}
},
};
</script>
<style lang="less" scoped>
.content-box {
display: flex;
position: relative;
.nav {
position: sticky;
top: 40vh;
width: 27vw;
height: 100vh;
background: rgb(47, 113, 255);
overflow-y: scroll;
.nav-list {
display: flex;
align-items: center;
min-height: 10vh;
text-align: left;
box-sizing: border-box;
padding: 20px;
font-size: 40px;
}
.nav-list.ac {
background: rgb(247, 86, 86);
}
}
.nav::-webkit-scrollbar {
display: none;
}
.content {
width: 73vw;
height: 100vh;
background: aqua;
overflow-y: scroll;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch; /* 解决ios滑动不流畅问题 */
transition: 0.3s ease-in all;
.content-list {
height: 100vh;
font-size: 50px;
text-align: center;
transition: 0.3s ease-in all;
.title {
height: 5vh;
line-height: 5vh;
color: #fff;
background: rgb(209, 92, 224);
position: sticky;
top: 0;
}
}
}
.content::-webkit-scrollbar {
display: none;
}
}
</style>
Vue左右联动
于 2021-08-26 16:09:28 首次发布