微信小程序商城分类滚动列表锚点的项目实践
一、需求背景
最近接了个商城小程序的项目,在做商品分类页面的时候,一开始是普通分类列表,但是客户觉得效果不理想,想要滚动列表的效果,需要实现以下功能:
- 列表滑动效果;
- 滑动切换分类;
- 点击分类跳转到相应的分类位置。
思路是用使用官方组件scroll-view,给每个分类(子元素)添加锚点,然后记录每个分类项的高度,监听scroll-view组件滚动事件,计算分类的跳转
二、效果演示
三、核心代码实现
下面要使用到的方法都来自于查阅微信小程序官方文档
创建一个scoll-view 并配置需要用到的属性scroll-into-view根据文档描述此属性是子元素的id,值为哪个就跳到那个子元素。为了使跳转不显得生硬,再添加scroll-with-animation属性,然后创建动态生成分类的dom元素并为每个子元素添加相应的id
<view class="content">
<!-- 左侧分类 -->
<scroll-view scroll-y scroll-with-animation class="left" style="height:{{height}}rpx;" scroll-into-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-into-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;" class="lazy" data-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
3.监听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插件,具体方法百度一下,很简单。
到此这篇关于微信小程序商城分类滚动列表锚点的项目实践的文章就介绍到这了,更多相关小程序滚动列表锚点内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341