效果如下:
<scroll-view scroll-y=”true” style=’height:100%;’>
<view wx:for=”{{cates}}” class=”nav-item {{index === navActive ? ‘active’:”}}” wx:key=”{{index}}” data-index=”{{index}}”
catchtap=’chooseType’ data-id=’type{{index}}’
>
{{item.typeName}}
<view class=’Badge’ wx:if=”{{item.num > 0}}”>{{item.num}}</view>
</view>
</scroll-view>
一:点击分类内容区域对应滚动
动态绑定 navActive 的值,来决定哪个分类被选中,选中类则为 active, 否则为空,将选中样式写到 active 里。然后为点左边右边跳到相应商品,这里主要用到的锚点,小程序在 scroll-view 里提供了一个 scroll-into-view
<scroll-view scroll-y=”true” style=’height:{{conHeight}}rpx;’ scroll-into-view=”{{contentActive}}” scroll-with-animation=”true” bindscroll=”onScroll”>
<block wx:if=”{{retlist.length > 0}}”>
<view class=’contlist’ wx:for=”{{retlist}}” wx:key=”key” wx:for-index=”parentIndex”>
<view class=’title’ id=’type{{parentIndex}}’>{{item.typeName}}</view>
<view wx:for=”{{item.goodsList}}” wx:for-item=”goods” wx:key=”key” class=’goodsItem’>
<view class=”icon”>
<image src=”{{goods.goods_pic}}” style=”width: 120rpx;height: 120rpx” data-id=”{{goods.id}}” bindtap=”togglePopup”></image>
</view>
<view class=’info’>
<view class=’head flex’>
<text class=’name’>{{goods.goods_name}}</text>
<text class=’extra’ wx:if=”{{item.typeName===’ 特惠商品 ’}}”> 仅剩 {{goods.left_num}} 份 </text>
</view>
<view class=’foot flex flex-cross-center’>
…
</view>
</view>
</view>
</view>
</block>
<block wx:else>
<view> 暂无商品 </view>
</block>
</scroll-view>
scroll-into-view 就是内容栏的一个钩子, 通过控制 contentActive 的值来控制内容栏的显示。滚动的问题好解决,那么联动呢?我们需要的联动必须是左右相互的,即点击导航栏,内容会跟着滚动到对应的位置,滑动内容区域,导航栏也会有对应的动作,比如高亮。小程序的组件属性中有一个 scroll-into-view 的属性
// 点击导航栏时就可以通过小程序的方法拿到 id 和该项目的索引,并赋值
chooseType:function(e){// 分类选择
// console.log(e)
let dataSet = e.currentTarget.dataset;
this.setData({
navActive: dataSet.index,
contentActive:dataSet.id,
})
},
这样通过点击导航栏,内容也会自动滚动到指定位置了,并且导航栏对应的标题高亮效果
二:反过来,右边联动左边就比较麻烦了,小程序没有提供反向联动的功能,只能自己实现了。**
这里的绑定的高度是 scroll-view 的高度,因为我这里有 240 的 head 和 150 的 foot,所以才减 -240-150,请根据实际情况决定写法
wx.getSystemInfo({
success: function (res) {
let windowHeight = (res.windowHeight * (750 / res.windowWidth)); // 将高度乘以换算后的该设备的 rpx 与 px 的比例
//console.log(windowHeight) // 最后获得转化后得 rpx 单位的窗口高度
_this.setData({
conHeight: windowHeight-240-150,
})
}
})
获得每个元素据顶部的高度,组成一个数组,通过高度与 scrollTop 的对比来知道目前滑动到那个区域
let heightArr = [];
let h = 0;
// 创建节点选择器
const query = wx.createSelectorQuery();
// 选择 id
query.selectAll(‘.contlist’).boundingClientRect()
query.exec(function (res) {
//res 就是 所有标签为 contlist 的元素的信息 的数组
res[0].forEach((item) => {
h += item.height;
heightArr.push(h);
})
_this.setData({
heightArr: heightArr
})
// console.log(heightArr)
})
1. 当 scroll-view 滚动的时候,就可以获取到滚动的距离,并动态计算滚动区间,是在 heightArr 的哪个区间里面,并返回对应的索引。2. 因为是通过实时监控来判断的,如果判断完了以后就绑定数据的话,就会不停的 setData, 所以我这里设置了一个 lastActive, 只有每次被选中分类变的时候,才会 setData
onScroll:function(e){
const scrollTop = e.detail.scrollTop;
const scorllArr = this.data.heightArr;
const _this = this;
if (scrollTop >= scorllArr[scorllArr.length – 1] – (_this.data.conHeight/2)){
return;
}else{
for(let i=0;i< scorllArr.length; i++){
if(scrollTop >= 0 && scrollTop <scorllArr[0]){
if (0 != _this.data.lastActive) {
_this.setData({
navActive: 0,
lastActive:0,
})
}
}else if(scrollTop >=scorllArr[i-1] && scrollTop <scorllArr[i]){
if (i != _this.data.lastActive) {
_this.setData({
navActive: i,
lastActive: i,
})
}
}
}
}
},
参考
https://blog.csdn.net/dongguan_123/article/details/80598107https://blog.csdn.net/weixin_42488377/article/details/81162676