微信小程序“返回顶部”实现

bolelee
  • 1.2k

需求:页面的信息分页获取,当滑动到底部(onReachBottom)时加载更多信息(下一页),当内容足够多的时候,有返回顶部按钮较好,虽然小程序本身有返回顶部的交互(IOS点击顶部状态栏,安卓双击导航栏),但可能有的用户不知道这个交互,因此,会有添加“返回顶部”按钮的需求;

实现方式:搜过了实现方案,有通过scroll-view来监听scroll,点击返回按钮时改变其scroll-top的方式(见此处),大致实现如下:

xx.js

Page({
  data: {
    scrollTop: 0,
    floorstatus: false
  },
  goTop: function(e){
    this.setData({
      scrollTop: 0
    })
  },
  scroll: function(e) {
    if(e.detail.scrollTop > 500) {
      this.setData({
        floorstatus: true
      });
    } else {
      this.setData({
        floorstatus: false
      });
    }
  },
  getMore: function() {
    ...
  }
})
xx.wxml

<scroll-view scroll-y="true" bindscroll="scroll" scroll-top="{{scrollTop}}" bindscrolltolower="getMore" style="position:absolute; top:0; left:0; right:0; bottom:0;">
  ...页面的内容
</scroll-view>

<view class="widget-goTop" bindtap="goTop" wx:if="{{ floorstatus }}">
  <view class="gotop-wrap">
    <view class="icon icon-top"></view> <view>顶部</view>
  </view>
</view>
xx.wxss

/* 返回顶部 */
.widget-goTop { 
  position: fixed; 
  bottom: 125px; 
  right: 5px; 
  background: rgba(0,0,0,0.48); 
  border-radius: 50%; 
  overflow: hidden; 
  z-index: 500; 
} 
.widget-goTop .gotop-wrap { 
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  width: 50px; 
  height: 50px; 
  font-size: 12px; 
  color: #fff; 
  border-radius: 50%; 
  background-color: rgba(0,0,0,0.8); 
  -webkit-background-size: 50px auto; 
}

以上方案存在的问题:

  • 加载更多:同样的请求可能被不定次数地重复运行,因为bindscrolltolower多次被触发,但每次其被触发的请求未完成,于是便又发起了仍是获取该页数据的请求,导致重复获取数据;
    解决方法:这个问题可以通过在发起请求前确认当前无请求正在进行解决,比如加一个isLoading,当请求发起时其为true,请求成功后重置为false,要发起请求前确保isLoading为false,以此避免重复请求同一页数据。

问题:除了上述加载更多这个问题,用此方法实现返回顶部,经测试,数据较多页时,会出现数据显示慢,页面部分内容空白;页面可能卡住;不知道这些问题跟这个实现方案有没有关系,不采用此方案,是否有其他方案可实现“返回顶部”? (总感觉非要加一个scroll-view包裹来实现,似乎不是最好的方案)

回复
阅读 25.7k
4 个回答
✓ 已被采纳
kris
  • 3
新手上路,请多包涵

原先的页面触底加载更多函数失效

用bindtouchmove获取WXML节点信息的相关函数,获取顶部滚动出去的距离,从而控制返回顶部按钮的显示

<view class="container" bindtouchmove="handletouchmove">
    ...
</view>

<!-- 返回顶部按钮 -->
<view class='gotop' wx:if="{{showGoTop}}" bindtap='backToTop'>
  <image src='../../images/icon/gotop.png' mode='widthFix'></image>
</view>
Page({
  data:{
    showGoTop: false,
  },
  handletouchmove: function () {
    this.queryMultipleNodes();
  },
  //获取屏幕滚动出去的高度
  queryMultipleNodes: function () {
    var self = this;
    var query = wx.createSelectorQuery()
    query.select('#header').boundingClientRect()
    query.selectViewport().scrollOffset()
    query.exec(function (res) {
      res[0].top       // 节点的上边界坐标
      //如果顶部的距离超过200   就显示GoTop按钮
      if(res[0].top < -300) {
        self.setData({
          showGoTop: true
        })
      }
      else {
        self.setData({
          showGoTop: false
        })
      }
    })
  },
  //返回顶部
  backToTop: function () {
    wx.pageScrollTo({
      scrollTop: 0,
      duration: 400
    });
    this.setData({
      showGoTop: false
    })
  }
})

this.scrollTop = this.scrollTop === 0 ? 1 : 0;
这个scrollTop:0 是不起效的,应该设置为为小于0的值,当然,在滚动到一定的距离之后回到顶部按钮显示绑定的点击事件生效;如果隐藏后滚动到一定的距离再次出现点击事件是不生效的

宣传栏