微信小程序 触底加载更新 虚拟列表渲染

  <wxs module='filter'>
  var includesList = function(list,currentIndex){
    if(list){
      return list.indexOf(currentIndex) > -1
    }
  }
  module.exports.includesList =  includesList;
  </wxs>
  <scroll-view  style='height: 76vh;' 
    scroll-y="true" 
    bindscrolltolower="loadMore"
    bindscroll="scrollFn"
  >   
  <view class="template_container">
    <view wx:for="{{list}}" wx:for-index="pageNum" id="item{{pageNum}}" wx:key="pageNum">
    <block wx:if="{{filter.includesList(visualIndex,pageNum)}}">
      <view class="item-list" wx:for="{{item}}" wx:key="item">
        <text class="">{{item.idx}}</text>
      </view>
    </block>
    <block wx:else>
      <view class="item-visible" style="height:{{pageHeight[pageNum]}}px"></view>
    </block>
  </view>
</view>
</scroll-view>  
// pages/commodity/index.js
import { throttle } from './utils'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    list: [],          // 所有数据
    visualIndex: [0],          //  展示区域
    pageHeight: [],
    scrollTop: 5, // 设定触发条件的距离
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.setData({ tabBarList: app.globalData.tabBarList });

    this.index = 0;
    this.currentIndex = 0;           // 当前页数 pageNum
    this.pageHeight = [];            // 每屏高度存储
    this.allList = [];               // 获取到的所有数据
    this.systemHeight = 0;           // 屏幕高度
    this.visualIndex = [];           // 存储可视区域pageNum
    const arr = [
      { idx: this.index++ },
      { idx: this.index++ },
      { idx: this.index++ },
      { idx: this.index++ },
      { idx: this.index++ },
    ]
    this.setData({ [`list[${this.currentIndex}]`]: arr }, () => {
      this.setPageHeight();
    });
    this.getSystemInfo();
  },
  // 获取屏幕高度
  getSystemInfo() {

    wx.getSystemInfo({
      success: (res) => {
        let { windowHeight } = res;
        this.systemHeight = windowHeight;
      }
    })
  },
  // 获取每屏高度
  setPageHeight() {
    setTimeout(() => {
      wx.nextTick(() => {
        let that = this;
        let currentIndex = this.currentIndex;
        let query = wx.createSelectorQuery();
        query.select(`#item${currentIndex}`).boundingClientRect()
        query.exec(function (res) {
          that.pageHeight[currentIndex] = res[0] && res[0].height;
          that.setData({
            pageHeight: that.pageHeight
          })
        })
      })
    }, 100);
  },
  loadMore: function () {
    this.currentIndex++;            // 触底+1
    const arr = [
      { idx: this.index++ },
      { idx: this.index++ },
      { idx: this.index++ },
      { idx: this.index++ },
      { idx: this.index++ },
    ]
    this.setData({ [`list[${this.currentIndex}]`]: arr }, () => {
      this.setPageHeight()
    })
  },
  // 滚动距离计算
  scrollFn: throttle(function (e) {
    let pageScrollTop = e[0].detail.scrollTop;
    let that = this;
    // 滚动计算现在处于那一个分页的屏
    let scrollTop = 0;
    for (var i = 0; i < this.pageHeight.length; i++) {
      scrollTop = scrollTop + this.pageHeight[i];
      if (scrollTop > pageScrollTop + this.systemHeight - 50) {
        this.currentIndex = i;
        this.visualIndex = [i - 1, i, i + 1];
        that.setData({
          visualIndex: this.visualIndex
        })
        break;
      }
    }
  }, 200)
})
const throttle = (fn, interval) => {
  var enterTime = 0; //触发的时间
  var gapTime = interval || 300; //间隔时间,如果interval不传值,默认为300ms
  return function () {
    var that = this;
    var backTime = new Date(); //第一次函数return即触发的时间
    if (backTime - enterTime > gapTime) {
      fn.call(that, arguments);
      enterTime = backTime; //赋值给第一次触发的时间 保存第二次触发时间
    }
  };
}

module.exports = {
  throttle
}

 

posted @ 2024-10-18 15:16  前端搬运工bug  阅读(0)  评论(0编辑  收藏  举报