先放效果图
效果图代码截图
wxml js js代码解释
主体html其实东西很少,主要分为两部分:一个主体的view
和一个长内容的scroll-view
;
当前项的内容都放置在scroll-view
内,只有在scroll-view
滚动到底部时,才会触发外层的上拉滚动;
监听touch start
和touch end
也只是为了区别用户是否上拉足够的距离,如果距离不够的话同样也不会触发滚动;
scroll-view
内scroll-into-view
的作用是,当用户上拉切换项的时候,把当前的视角定位在scroll-view
的顶部;单纯的用户体验方面的设计;
我是通过wx.pageScrollTo()
这个方法来进行页面滚动的,如果你有其他的好方法也欢迎交流;
实际上我这里是两次滚动,第一次滚动一屏的距离,完成后再滚动回一屏的距离;
此时页面的滚动条其实还在顶部,滚动距离为0;因为第二次滚动没有动画,给用户一种向下滚动了一屏的感觉;
原理解析
我们的数据始终是一个长度为2的数组scroll_list
;
这里的view
和scroll-view
我们叫做外、内两部分;
外的主要作用是监听用户上拉距离,内用来控制当前可滚动的是内还是外;
当内滚动到底时,lower === true
,用户再次上拉时,开始计算用户上拉距离;
scrollToLower() {
this.lower = true;
},
touchstart(e) {
if (!this.lower) {
this.start = undefined;
return;
}
this.start = e.touches[0].clientY; // 用户点击位置的y坐标
}
如果上拉距离大于200,调用wx.pageScrollTo()
,滚动一屏;如果距离大于0但小于200,把用户上拉的距离滚动回去;如果小于0,则用户滚动为内,将监听用户的上拉取消;
touchend(e) {
if (!this.start) return;
const move = this.start - e.changedTouches[0].clientY; // 计算上拉距离
const { view } = this; // 屏幕高度
const _this = this;
if (move > 200) {
wx.pageScrollTo({
scrollTop: view,
selector: '.main',
complete() {
wx.pageScrollTo({
scrollTop: 0,
selector: '.main',
duration: 0,
complete() {
const { scroll_list } = _this.data; // 初始为scroll_list: [1, 2]
scroll_list.shift();
scroll_list.push(_this.index); // 第一次滚动后scroll_list: [2, 3]
_this.setData({
item_id: 'img', // 将内的滚动位置设置为内的顶部
scroll_list
})
++_this.index;
_this.lower = false; // 初始化滚动监听枷锁
_this.start = undefined; // 初始化点击起点位置
}
})
}
})
} else if (0 < move <= 200) {
wx.pageScrollTo({
scrollTop: 0,
selector: '.main',
complete() {
_this.start = undefined;
}
})
} else {
this.lower = false;
}
}
网友评论