注册
web

微信小程序商城分类滚动列表锚点

一、需求背景

最近接了个商城小程序的项目,在做商品分类页面的时候,一开始是普通分类列表,但是客户觉得效果不理想,想要滚动列表的效果,需要实现以下功能:

  1. 列表滑动效果;
  2. 滑动切换分类;
  3. 点击分类跳转到相应的分类位置。

思路是用使用官方组件scroll-view,给每个分类(子元素)添加锚点,然后记录每个分类项的高度,监听scroll-view组件滚动事件,计算分类的跳转

二、效果演示

录制_2023_04_18_11_25_56_701.gif

三、核心代码实现

下面要使用到的方法都来自于查阅微信小程序官方文档

  1. 创建一个scoll-view 并配置需要用到的属性scroll-int0-view 根据文档描述此属性是子元素的id,值为哪个就跳到那个子元素。为了使跳转不显得生硬,再添加scroll-with-animation属性,然后创建动态生成分类的dom元素并为每个子元素添加相应的id

image.png

        <view class="content">

<scroll-view scroll-y scroll-with-animation class="left" style="height:{{height}}rpx;" scroll-int0-view='{{leftId}}'>
<view id='left{{index}}' class="left-item {{activeKey===index?'active':''}}" wx:for="{{navData}}" data-index='{{index}}' wx:key='id' bindtap="onChange">
<text class='name'>{{item.name}}text>
view>
scroll-view>

<scroll-view class="right" scroll-y scroll-with-animation scroll-int0-view="{{selectedId}}" bindscroll="changeScroll" style='height:{{height}}rpx;'>

<view class="item" wx:for="{{goodslist}}" wx:key="id" id='type{{index}}'>

<view class="type">【{{item.name}}】view>

<view class="item-list">
<navigator class="list-item" wx:for="{{item.list}}" wx:for-item='key' wx:key="id" url='/pages/goods/goods?id={{key.id}}'>
<image style="width: 100%; height: 180rpx;" src="{{key.imgurl}}" />
<view class="item-name">{{key.goods_name}}view>
navigator>
view>
<view wx:if="{{item.list.length===0}}" class="nodata">
暂无商品
view>
view>
scroll-view>
view>

css部分

这里用到了吸顶效果position: sticky;

        .content {
width: 100%;
height: calc(100% - 108rpx);
overflow-y: hidden;
display: flex;

.left {
height: 100%;
overflow-y: scroll;
.left-item {
width: 100%;
padding: 20rpx;
box-sizing: border-box;

.name {
word-wrap: break-word;
font-size: 28rpx;
color: #323233;
}
}

.active {
border-left: 6rpx #ee0a24 solid;
background-color: #fff;
}
}

.right {
flex: 1;

.item {
position: relative;
padding: 20rpx;

.type {
margin-bottom: 10rpx;
padding: 5rpx;
position: sticky;
top: 0;
background-color: #fff;
}

.item-list {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 20rpx;
text-align: center;

.item-name {
color: #3a3a3a;
font-size: 26rpx;
margin-top: 10rpx;
}
}

.nodata{
padding: 20rpx;
color: #ccc;
}
}
}
}

2. 在列表渲染完成之后计算出每个分类的高度并且保存成一个数组

// 用到的data
data:{
// 分类列表
navData:[],
// 商品列表
goodslist:[],
// 左侧分类选中项 分类列表数组的下标
activeKey:0,
// 计算出的锚点的位置
heightList:[],
// 右侧子元素的锚点
selectedId: 'type0',
// 左侧分类的锚点
leftId:'left0',
// scroll-view 的高度
height:0
},
onShow() {
let Height = 0;
wx.getSystemInfo({
success: (res) => {
Height = res.windowHeight
}
})
const query = wx.createSelectorQuery();
query.selectAll('.search').boundingClientRect()
query.exec((res) => {
// 计算滚动列表的高度 视口高度减去顶部高度 *2是因为拿到的是px 虽然也可以 但是我们通常使用的是rpx
this.setData({
height: (Height - res[0][0].height) * 2
})
})
},

//计算右侧每个锚点的高距离顶部的高
selectHeight() {
let h = 0;
const query = wx.createSelectorQuery();
query.exec((res) => {
console.log('res', res)
let arr=res[0].map((item,index)=>{
h+ = item.height
return h
})
this.setData({
heightList: arr,
})
console.log('height', this.data.heightList)
})
},

使用到的相关API image.png

  1. 监听scroll-view的滚动事件,通过滚动位置计算当前是哪个分类。
changeScroll(e) {
// 获取距离顶部的距离
let scrollTop = e.detail.scrollTop;
// 当前分类选中项,分类列表下标
let {activeKey,heightList} = this.data;
// 防止超出分类 判断滚动距离是否超过当前分类距离顶部高度
if (activeKey + 1 < heightList.length && scrollTop >= heightList[activeKey]) {
this.setData({
// 左侧分类选中项改变
activeKey: activeKey + 1,
// 左侧锚点对应位置
leftId: `left${activeKey + 1}`
})
}
if (activeKey - 1 >= 0 && scrollTop < heightList\[activeKey - 1]) {
this.setData({
activeKey: activeKey - 1,
leftId: `left${activeKey - 1}`
})
}
},

4. 监听分类列表点击事件,点击分类跳转相应的分类商品列表

onChange(event) {
let index = event.currentTarget.dataset.index
this.setData({
activeKey: index,
selectId: "item" + index
});
},

四、总结

左侧分类一开始是用的vantUI的滚动列表,但是分类过多就不会随着滑动分类滚动到可视位置,所以改成自定义组件,反正也很简单。

最初是想根据右侧滚动位置给左侧的scroll-view添加scroll-top,虽然实现,但是有时会有一点小问题目前没有想好怎么解决,改用右侧相同方法实现可以解决。

css部分使用scss编写,使用的是vscode的easy scss插件,具体方法百度一下,很简单。


作者:丝网如风
来源:juejin.cn/post/7223211123960660028

0 个评论

要回复文章请先登录注册