解题思路
1.左右的结构(scroll-view)
2.左侧点击的时候,要跟右侧的id对应上
3.右侧上下滑动的时候,左侧的id要对应上
(右侧滑动时会产生滚动高度--scrollTop(st))
如:人气Top的高度有500 --- st>=0 && st<500
大师咖啡的高度有300 --- st>=500 && st<800
小鹿茶精选的高度有270 --- st>=800 && st<=1070
获取每个区块的高度 push到数组中[ 0 , 500 , 800 , 1070]
arr[i] < st < arr[i+1]
<!-- WXML -->
<view class="main">
<!-- 左侧 -->
<!-- 自定义属性:data+变量名 -->
<scroll-view scroll-y="true" class="left" scroll-into-view="{{leftId}}">
<view wx:for="{{menuArr}}" wx:key="*this" data-myid="{{item.id}}" id="left{{item.id}}" class="scroll-view-item {{leftActiveNum==item.id? 'active':''}}" bindtap="leftClickFn">{{item.title}}</view>
</scroll-view>
<!-- 右侧 -->
<scroll-view scroll-y="true" class="right" scroll-with-animation="true" bindscroll="rightScrollFn" scroll-into-view="{{rightId}}">
<view wx:for="{{menuArr}}" wx:key="*this" id="right{{item.id}}" class="scroll-view-item rightblock">
<view class="title">{{item.title}}</view>
<view class="content">
<view class="box" wx:for="{{item.subArr}}" wx:key="*this" wx:for-item="items">
<!-- wx:for-item="items" 把wx:for="{{item.subArr}}"中的item替换为items,就避免混淆 -->
<image src="{{items.imgSrc}}" mode="widthFix"></image>
<text>{{items.imgDesc}}</text>
</view>
</view>
</view>
</scroll-view>
</view>
/* WXSS */
.main{
width: 100vw;
/* cslc计算:- 号前后必须加空格,不然不起效果 */
height: calc(100vh - calc(100vw/1080*520));
background-color: #fff;
padding-top: 10rpx;
}
/* 左侧 */
.main .left{
width: 25%;
float: left;
height: calc(100vh - calc(100vw/1080*520));
border-right: 1rpx solid #000;
/* box-sizing: border-box; */
}
.main .left view{
/* width: 100%; */
height: 80rpx;
line-height: 80rpx;
text-align: center;
background-color: #fff;
border-bottom: 1rpx solid #000;
position: relative;
}
.main .left view::before{
content: "";
width: 10rpx;
height:78rpx;
background-color: #fff;
position: absolute;
left: 0;
top: 1rpx;
}
.main .left view.active::before{
background-color: #333999;
}
/* 右侧 */
.right{
width: 74%;
height: calc(100vh - calc(100vw/1080*520));
float: right;
padding: 0 10rpx;
box-sizing: border-box;
}
.right .title{
height: 60rpx;
line-height: 60rpx;
}
.right .content{
background-color: #fff;
padding: 1%;
box-sizing: border-box;
display: flex;
/* 从左到右排序 */
justify-content: flex-start;
flex-wrap:wrap ;
text-align: center;
margin-left: 1%;
padding-right: 0;
}
.box{
width: 32%;
margin-right: 1%;
margin-bottom: 10rpx;
}
.box image{
width: 90%;
/* display: block; */
}
.box text{
font-size: 28rpx;
display: block;
/* 超出隐藏 */
overflow: hidden;
/* 超出以...显示 */
text-overflow: ellipsis;
/* 不换行 */
white-space: nowrap;
}
//JS
// pages/menu/menu.js
Page({
data: {
// banner的轮播图
swiperArr: [
"/images/banner/menubanner1.jpg",
"/images/banner/menubanner2.jpg",
"/images/banner/menubanner3.jpg"
],
// 图片数组
menuArr: [{
"id": 0,
"title": "人气Top",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "桃桃芝士红宝石"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "咖啡风味安慕希"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "陨石拿铁"
}
]
},
{
"id": 1,
"title": "大师咖啡",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "冲绳黑糖拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "陨石拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "拿铁"
}
]
},
{
"id": 2,
"title": "小鹿茶精选",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "标准美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "加浓美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "焦糖标准美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "焦糖加浓拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
}
]
},
{
"id": 3,
"title": "瑞纳冰",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "乐岛桃桃冰"
}]
},
{
"id": 4,
"title": "鲜榨果蔬汁",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "NFC鲜榨橙汁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "NFC鲜榨西柚汁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "猕猴桃复合果汁"
}
]
},
{
"id": 5,
"title": "经典饮品",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "巧克力"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "纯牛奶"
}
]
},
{
"id": 6,
"title": "健康轻食",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "京味烤鸭鲜蔬卷"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "夏威夷菠萝火山卷"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "火腿芝士羊角"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "鸡肉卷"
}
]
}
],
// 定义左侧的id
leftId: "left0",
// 左侧当前项active
leftActiveNum: 0,
// 右侧id
rightId: "right0",
// 右侧高度数组
heightArr: []
},
// 等同于生命周期的mounted阶段 -- vue中的Mounted并没有100%保证组件渲染完成 - 有时间差
onReady() {
let _this = this;
// 给个定时器解决onReady带来的时间差渲染的数据错乱
setTimeout(() => {
let initArr = [0]; //初始数组
let initNum = 0; //初始默认值
const query = wx.createSelectorQuery()
query.selectAll('.rightblock').boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(function (res) {
res[0].map(val => {
initNum += val.height;
initArr.push(initNum)
})
// 获取每个区块的高度 --- 并定义个变量(heightArr)接收、存储这个高度
// console.log(initArr);
_this.setData({
heightArr: initArr
})
})
}, 500)
},
// 左侧点击方法
leftClickFn(e) {
// console.log(e.target.dataset.myid);
// console.log(this.data.heightArr);
this.setData({
leftActiveNum: e.target.dataset.myid,
leftId: "left" + e.target.dataset.myid,
rightId: "right" + e.target.dataset.myid,
})
},
// 右侧滚动方法
rightScrollFn(e) {
// console.log(e.detail.scrollTop);
let st = e.detail.scrollTop;
let myArr = this.data.heightArr;
for (let i = 0; i < myArr.length; i++) {
if (st >= myArr[i] && st < myArr[i + 1]-5) {
this.setData({
leftId: "left" + i,
leftActiveNum: i
})
return;
}
}
}
})