微信小程序无限滚动列表

4,086 阅读2分钟

先放效果图



代码截图





代码解释

主体html其实东西很少,主要分为两部分:一个主体的view和一个长内容的scroll-view

当前项的内容都放置在scroll-view内,只有在scroll-view滚动到底部时,才会触发外层的上拉滚动;

监听touch starttouch end也只是为了区别用户是否上拉足够的距离,如果距离不够的话同样也不会触发滚动;

scroll-viewscroll-into-view的作用是,当用户上拉切换项的时候,把当前的视角定位在scroll-view的顶部;单纯的用户体验方面的设计;

我是通过wx.pageScrollTo()这个方法来进行页面滚动的,如果你有其他的好方法也欢迎交流;

实际上我这里是两次滚动,第一次滚动一屏的距离,完成后再滚动回一屏的距离;

此时页面的滚动条其实还在顶部,滚动距离为0;因为第二次滚动没有动画,给用户一种向下滚动了一屏的感觉;

原理解析

我们的数据始终是一个长度为2的数组scroll_list

这里的viewscroll-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;    }  }