wepy-scroll
微信小程序楼层跳跃, 滚动楼层. 滚动商品时触发分类切换, 商品分类联动
运行
npm install
npm run dev
用微信开发工具打开目录下的dist文件夹
position: sticky;
改新属性可以让一个元素在滚动到顶部是自动吸顶, 类似于fixed, 只是之前我们的做法都是使用fixed(需要检测滚动距离,消耗cpu性能), 必须要给定top right left bottom 任意一个属性的值.
使用scroll-view,
让scroll-view里面的元素使用sticky属性自动吸顶, 必须要使用一个view作为父元素将scroll-view里的元素都包住, 不然 在滑动一整个屏幕的高度之后吸顶的元素会被顶走
<view>
<scroll-view class="category-scroll"
scroll-into-view="{{scrollInTo}}"
bindscroll="scrolling"
scroll-with-animation="true" scroll-y="true">
<view>
<view class='cs-banner'>banner</view>
<view class="cs-fix">
<view>
<repeat for="{{fruits}}" key="index">
<view class="cate {{currentCategory==index?'selected':''}}"
@tap.stop="clickScrollInTo"
data-name="{{item.name}}">{{item.name}}</view>
</repeat>
</view>
</view>
<view class="products" id="prds">
<repeat for="{{fruits}}" key="index" item="item" index="index">
<view class="product" id="{{item.name}}">{{item.name}}</view>
<view class="productBox" wx:for="{{item.num}}" wx:for-item="itm" wx:key="idx" wx:for-index="idx">
第{{idx}}个{{item.name}}
</view>
</repeat>
</view>
</view>
</scroll-view>
</view>
scroll-view属性
scroll-into-view="{{scrollInTo}}" 可以跳转到scroll-view里的某个元素, 根据id bindscroll="scrolling" scroll-view滚动时会触发该函数 scroll-with-animation="true" 滚动时会有缓动动画 scroll-y="true" 允许纵向滚动
js逻辑
import wepy from 'wepy'
export default class categoryScroll extends wepy.page {
config = {
navigationBarTitleText: '楼层滚动'
}
components = {}
data = {
fruits: [
{name: 'apple', num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},
{name: 'banana', num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},
{name: 'orange', num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},
{name: 'pineapple', num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},
{name: 'watermelon', num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
],
// 当前分类的索引
currentCategory: 0,
// 每个分类距离顶部的高度的数组
productsTop: [],
categoryTop: 10000,
// 用于存储每次滚动结束之后的距离, 可用来判断滚动的方向
moveStartPos: 0,
// 点击分类的名称, 用于点击跳转
scrollInTo: ''
}
computed = {}
// onPageScroll (e) { s
onScrollViewScroll (e) {
// 当前滚动的距离
let scrollTop = e.scrollTop
// moveStartPos记录着上一次滚动完成时的位置, 用于判断滚动方向
// 如果现在的滚动距离大于moveStartPos说明正在往下滚动
if (scrollTop > this.moveStartPos) {
this.moveStartPos = scrollTop
// 遍历每个商品距离顶部的距离
this.productsTop.forEach((item, index) => {
// 如果滚动的距离大于某个商品到顶部的距离说明该商品到了顶部, 减10是为了减少触发距离
if (scrollTop > item.top - 10) {
// 当前分类的索引小于满足条件的商品索引就赋值, 跳到下一个分类
if (this.currentCategory < index) {
this.currentCategory = index
this.$apply()
}
}
})
// 如果现在的滚动距离小于moveStartPos说明正在往上滚动
} else if (scrollTop < this.moveStartPos) {
this.moveStartPos = scrollTop
this.productsTop.forEach((item, index) => {
if (scrollTop < item.top - 10) {
if (this.currentCategory >= index) {
this.currentCategory = index ? index - 1 : index
this.$apply()
}
}
})
}
this.$apply()
}
methods = {
// scroll-view滚动时触发
scrolling (e) {
// 将当前的距离传入
this.onScrollViewScroll({scrollTop: e.detail.scrollTop})
},
// 点击分类跳转
clickScrollInTo (e) {
this.scrollInTo = e.currentTarget.dataset.name
this.$apply()
}
}
onReady () {
// 页面准备完成之后获取每个分类距离顶部的高度, 存储在数组productsTop中
var query = wx.createSelectorQuery()
this.productsTop = []
query.selectAll('.product').boundingClientRect((rect) => {
rect.forEach((item, index) => {
this.productsTop.push({top: item.top})
})
this.$apply()
})
query.selectAll('.cs-fix').boundingClientRect((rect) => {
this.categoryTop = rect[0].top
this.$apply()
}).exec()
}
}