前言
前段时间练手,写了这个小demo,因为觉得很多电商类、外卖类的程序都用的到,所以在这里跟大家交流一下。如果有更好的实现方法,也可以带带我。
这里有2个功能点:
- 点击左侧分类标签的时候,右边滚动到相对应的盒子的区域
- 右边滚动的时候,以顶部为点,滚动到哪个分类,左边就会滚动到对应的标签
先上效果图吧:
基本思路
因为微信没有锚点这东西,右边商品列表使用的是scroll-view原生组件,只能设置它的scroll-top
wxml代码块:
<my-swiper backgroundArr="{{backgroundArr}}" imgHeight="{{imgHeight}}"></my-swiper>
<view class="main">
<scroll-view class="left" scroll-y="true" scroll-into-view="left{{leftId}}">
<view id="left{{item.id}}" bindtap="leftClick" data-myindex="{{index}}" class="scroll-view-item {{leftNum==index?'active':''}}" wx:for="{{arr}}" wx:key="*this">{{item.title}}</view>
</scroll-view>
<scroll-view class="right" scroll-y="true" scroll-into-view="right{{rightId}}" scroll-with-animation="true" bindscroll="rightScroll">
<view id="right{{item.id}}" class="scroll-view-item box" wx:for="{{arr}}" wx:key="*this">
<view class="title">{{item.title}}</view>
<view class="content">
<view wx:for="{{item.subArr}}" wx:key="*this" wx:for-item="subItem">
<image src="{{subItem.imgSrc}}" mode="widthFix"></image>
<text>{{subItem.imgDesc}}</text>
</view>
</view>
</view>
</scroll-view>
</view>
左侧的分类栏是通过获取给每个分类提前设置好的ID值,进行样式的切换。点左侧跟右侧进行联动,就需要给右边的每个盒子一个ID,让左边的ID和右边ID还有左边的点击获取当前值都相等,就可以实现左侧的联动。
右侧的联动就需要获取到每个盒子的头部距离顶部的距离,然后把他们放到一个数组里,在右侧的事件中去遍历数组,同时获取我们滚动的距离跟数组中的盒子之间的值做判断,判断我们滚动了第几个盒子的范围内,然后就把相应的数组赋给左边。
js代码块:
Page({
data: {
backgroundArr: [
"/images/banner/menubanner1.jpg",
"/images/banner/menubanner2.jpg",
"/images/banner/menubanner3.jpg",
],
imgHeight: 520,
arr: [],
leftNum: 0,
// 左侧ID
leftId: 0,
// 右侧ID
rightId: 0,
//box盒子高度数组
boxheight: [],
},
// 左侧点击
leftClick(e) {
this.setData({
leftNum: e.currentTarget.dataset.myindex,
leftId: e.currentTarget.dataset.myindex,
rightId: e.currentTarget.dataset.myindex
})
},
// 右侧滚动
rightScroll(e) {
let st = e.detail.scrollTop
let boxarray = this.data.boxheight
let _this = this
for (var i = 0; i < boxarray.length; i++) {
if (st >= boxarray[i] - 10 && st < boxarray[i + 1] - 10) {
_this.setData({
leftNum: i,
leftId: i
})
return;
}
}
},
//onLoad的生命周期
onLoad: function () {
wx.cloud.callFunction({
name: "getmenuData"
}).then(res => {
this.setData({
arr: res.result.data[0].arr
})
this.computedHeight();
})
},
// 生命周期onReady(类似于mounted)
computedHeight: function () {
const _this = this;
setTimeout(() => {
//专门用来储存高度的
let heightArr = [0]
// 一开始的初始值
let baseNum = 0
const query = wx.createSelectorQuery()
query.selectAll('.box').boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(function (res) {
res[0].map(va => {
baseNum += va.height
heightArr.push(baseNum)
})
_this.setData({
boxheight: heightArr
})
})
}, 600);
}
})
项目地址:
整个小程序的代码放在gitee仓库:gitee.com/wang_xiaohu…