参考方案一:
主要是来自知友提供的代码思路
原文链接:https://zhuanlan.zhihu.com/p/162904380
他的实现思路是:在页面可以使用onPageScroll来监听滚动条的位置
缺点:组件中是无法使用的 另外 页面中使用了overflow发现无法监听滚动条的位置
我使用了该思路 并加入了从后端请求数据的步骤 供大家参考
index.js
const utils = require('../utils/utils')
const app = getApp()
Page({
data: {
first:[
{
Id: 1,
Number: 'BN23656326561',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 2,
Number: 'BN23656326562',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 3,
Number: 'BN23656326563',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 4,
Number: 'BN23656326564',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 5,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 6,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 7,
Number: 'BN23656326567',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 8,
Number: 'BN23656326568',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 9,
Number: 'BN23656326569',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 10,
Number: 'BN23656326510',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
],
second:[
{
Id: 11,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 12,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 13,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 14,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 15,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 16,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 17,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 18,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 19,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 20,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
],
pagenum: 1,
pagesize: 10,
total: 12,
loading: true,
finishedLoading: false,
windowHeight:'',
pageScroll: false
},
onLoad: function(option){
// console.log("onLoad")
let that = this
wx.getSystemInfo({
success: function(res){
that.setData({
windowHeight: res.windowHeight
})
}
})
},
// 调用滚动条获取位置信息
onPageScroll: function(e){
// console.log(e)
if(e&&this.data.pageScroll == false){
this.setData({
pageScroll: true
})
}
let that = this
if(that.data.detail[that.data.detail.length - 1].hide){
return false
}
wx.getSystemInfo({
success: function(res){
that.setData({
windowHeight: res.windowHeight + e.scrollTop
})
}
})
// console.log(this.data.windowHeight,e.scrollTop)
var start = (that.data.pagenum - 1) * that.data.pagesize
for(let i = start; i < that.data.detail.length; i++){
if(that.data.detail[i].height <= that.data.windowHeight){
that.data.detail[i].hide = true
}else{
that.data.detail[i].hide = false
}
}
that.setData({
detail: that.data.detail
})
if(that.data.detail[that.data.detail.length-1].hide){
if(that.data.detail.length<that.data.total){
that.setData({
pagenum: that.data.pagenum+1,
loading: true
})
// 再次获取新的值
var data = that.initial()
}else{
that.setData({
finishedLoading: true
})
}
}
},
onShow() {
// console.log("onShow")
// 等待 获取从后端传过来的值
var data = this.initial()
},
async initial(){
this.setData({
pageScroll: false
})
const params = {
PageNum: this.data.pagenum,
PageSize: this.data.pagesize
}
await this.realIni(params)
},
getData(val){
var that = this
if(val.PageNum == 1){
let list = that.data.first
return new Promise((resolve, reject) => {
setTimeout(() => {
that.setData({
detail: that.data.first,
loading: false
})
resolve(list)
}, 2000)
})
}else{
var list = utils.deepCloneArr(that.data.detail)//深拷贝副本
list.push(...that.data.second)
return new Promise((resolve, reject) => {
setTimeout(() => {
that.setData({
loading: false,
detail: list
})
resolve(list)
}, 3000)
})
}
},
async realIni(val) {
const result = await this.getData(val)
var that = this
if(that.data.loading==false){
var start = (that.data.pagenum - 1) * that.data.pagesize
for(let i = start;i < result.length;i++){
// console.log('#curr'+ i)
wx.createSelectorQuery().select('#curr'+ i).boundingClientRect(function(rect){
// console.log(rect,rect.top)
result[i].height = rect.top
// console.log(result[i].height , that.data.windowHeight)
if(result[i].height <= that.data.windowHeight){
result[i].hide = true
}else{
result[i].hide = false
}
if(i==(result.length -1)){
that.setData({
detail: result
})
}
}).exec()
}
}
}
})
其中utils.js里面的深拷贝函数
// 对象深拷贝函数
const deepCloneArr = function(initalArr) {
var list = [];
list = JSON.parse(JSON.stringify(initalArr));
return list;
}
// 将深拷贝函数暴露出去
module.exports = {
deepCloneArr
}
index.json
{
"usingComponents": {
"mp-loading": "weui-miniprogram/loading/loading"
}
}
index.wxml
<view class="work {{pageScroll ? 'work-long': 'work-v'}}">
<view class="work-header">
<text>固定</text>
</view>
<view class="work-header-t">
</view>
<view class="lazyload">
<view wx:for="{{detail}}" wx:key="index" class="undeal-item {{item.hide?'animation':''}}" id="curr{{index}}">
<view wx:if="{{item.hide}}">
<view class="undeal-item-info">
<view class="undeal-item-info-oneline">
<view class="undeal-item-info-left">
<view class="undeal-item-info-left-label">编号</view>
<view class="undeal-item-info-left-value">{{item.Number}}</view>
</view>
<view class="undeal-item-info-right">
<text class="undeal-item-info-right-label">创建时间</text>
<text class="undeal-item-info-right-value">{{item.CreateTime}}</text>
</view>
</view>
<view class="undeal-item-info-twoline">
<view class="undeal-item-info-left">
<text class="undeal-item-info-left-label item-label-style">所属区域</text>
<text class="undeal-item-info-left-value item-style">{{item.RegionName}}</text>
</view>
<view class="undeal-item-info-left">
<text class="undeal-item-info-left-label item-label-style">目的地</text>
<text class="undeal-item-info-left-value item-style">{{item.Address}}</text>
</view>
</view>
</view>
</view>
</view>
<mp-loading wx:if="{{!finishedLoading}}" class="loading-style" type="dot-gray" show="{{loading}}"></mp-loading>
<text wx:else class="loading-txt">已经到底了...</text>
</view>
</view>
index.css
.work{
width: 100vw;
height: auto;
position: relative;
background-color: #F2F2F2;
}
.work-v{
height: 100vh;
}
.work-long{
height: 100%;
}
.work-header{
position: fixed;
/* position: sticky ; */
top: 0;
width: 100%;
height: 120rpx;
z-index: 1000;
float: left;
/* top: 0rpx; */
left: 0;
background-color: red;
padding: 19rpx 40rpx 4rpx 40rpx;
}
.work-header-t{
width: 100%;
height: 120rpx;
}
.lazyload{
width: 100%;
height: 100%;
background-color: pink;
/* 失效 */
/* height: calc(100vh - 120rpx); */
/* overflow-y: scroll; */
padding-bottom: calc(env(safe-area-inset-bottom) / 2);
}
.center{
width: 100%;
margin: 30rpx 10% 0;
float: left;
font-size: 26rpx;
height: 200rpx;
background-color: #fff;
}
.animation{
animation: center 1s;
}
@keyframes center{
from{
transform: scale(0.5);
}
to{
transform: scale(1);
}
}
/* 基本信息 */
.undeal-item{
height: 240rpx;
margin-top: 10rpx;
background-color: #fff;
}
.undeal-item-info{
padding: 0 26rpx 0rpx 38rpx;
display: flex;
flex-direction: column;
}
.undeal-item-info-oneline,
.undeal-item-info-twoline{
margin-top: 16rpx ;
font-size: 22rpx;
display: flex;
justify-content: space-between;
}
.undeal-item-info-oneline{
color: #237AE4;
}
.undeal-item-info-left{
flex: 1;
display: flex;
}
.undeal-item-info-right{
flex: 1;
display: flex;
}
.undeal-item-info-left-label{
width: 110rpx;
}
.undeal-item-info-right-label{
width: 120rpx;
}
.undeal-item-info-left-value,
.undeal-item-info-right-value{
justify-content: flex-end;
}
.item-label-style{
color: #666;
}
.item-style{
color: #333;
}
/* loading样式 */
.loading-style{
display: block;
padding-top: 40rpx;
padding-bottom: 40rpx;
}
.loading-txt{
font-size: 20rpx;
padding-bottom: 10rpx;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
color: #666;
background-color: lightgray;
}
对于上述方案有固定的头部区域,滚动条还是可以穿过,观感很不好
因此,带来第二种方案
参考方案二:
主要实现思路是:在需要懒加载的区域引入微信官方文档中的scroll-view组件
参考链接:https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html
lazyr.js
const utils = require('../../utils/utils')
const app = getApp()
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
first:[
{
Id: 1,
Number: 'BN23656326561',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 2,
Number: 'BN23656326562',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 3,
Number: 'BN23656326563',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 4,
Number: 'BN23656326564',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 5,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 6,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 7,
Number: 'BN23656326567',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 8,
Number: 'BN23656326568',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 9,
Number: 'BN23656326569',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 10,
Number: 'BN23656326510',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
],
second:[
{
Id: 11,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 12,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 13,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 14,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 15,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 16,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 17,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 18,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 19,
Number: 'BN23656326565',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
{
Id: 20,
Number: 'BN23656326566',
CreateTime: '2021/04/21 08:12:56',
RegionName: 'XXXXX',
Address: '一号研发楼'
},
],
query:'',
pagenum: 1,
pagesize: 10,
total: 20,
loading: true,
finishedLoading: false,
recycleList: [],
// 查询的触发标志
flag: '',
windowHeight: '',
areaInfo: {},
currentStatus: 0,
pageScroll: false
},
lifetimes: {
attached: function () {
this.setData({
pagenum: 1,
recycleList: [],
loading: true,
finishedLoading: false
})
var that = this
wx.getSystemInfo({
success: function(res){
that.setData({
windowHeight: res.windowHeight
})
}
})
},
ready: function(){
console.log("ready")
var inidetail = this.initial()
},
moved: function () {
},
detached: function () {
},
},
/* 组件的方法列表 */
methods: {
async initial(){
const params = {
PageNum: this.data.pagenum,
PageSize: this.data.pagesize
}
await this.realIni(params)
},
getData(val){
var that = this
if(val.PageNum == 1){
let list = that.data.first
return new Promise((resolve, reject) => {
setTimeout(() => {
that.setData({
loading: false,
recycleList: that.data.first
})
resolve(that.data.recycleList)
}, 2000)
})
}else{
// var list = utils.deepCloneArr(that.data.detail)//深拷贝副本
// list.push(...that.data.second)
return new Promise((resolve, reject) => {
setTimeout(() => {
let list = utils.deepCloneArr(that.data.recycleList)
list.push(...that.data.second)
that.setData({
loading: false,
recycleList: list
})
resolve(list)
}, 3000)
})
}
},
async realIni(val) {
const result = await this.getData(val)
console.log(result)
},
getScroll:function(e){
let that = this
if(that.data.recycleList.length<that.data.total){
that.setData({
pagenum: that.data.pagenum+1,
loading: true
})
// 再次获取新的值
var data = that.initial()
}else{
if(!that.data.finishedLoading){
that.setData({
finishedLoading: true
})
}
}
},
}
})
lazyr.json
{
"component": true,
"usingComponents": {
"mp-loading": "weui-miniprogram/loading/loading"
}
}
lazyr.wxml
<view class="work">
<view class="work-header-f">
<view class="work-header">
<text>固定</text>
</view>
<view class="work-header-t">
</view>
</view>
<view wx:if="{{ total > 0}}">
<scroll-view scroll-y="true" style='height:calc(100vh - 130rpx)'
class="{{ total>pagesize? '' : 'lazyload'}}"
bindscrolltolower="getScroll">
<view wx:for="{{recycleList}}" wx:key="index" class="undeal-item list_item_box" id="undeal{{id}}">
<view class="undeal-item-info">
<view class="undeal-item-info-oneline">
<view class="undeal-item-info-left">
<view class="undeal-item-info-left-label">编号</view>
<view class="undeal-item-info-left-value">{{item.Number}}</view>
</view>
<view class="undeal-item-info-right">
<text class="undeal-item-info-right-label">创建时间</text>
<text class="undeal-item-info-right-value">{{item.CreateTime}}</text>
</view>
</view>
<view class="undeal-item-info-twoline">
<view class="undeal-item-info-left">
<text class="undeal-item-info-left-label item-label-style">所属区域</text>
<text class="undeal-item-info-left-value item-style">{{item.RegionName}}</text>
</view>
<view class="undeal-item-info-left">
<text class="undeal-item-info-left-label item-label-style">目的地</text>
<text class="undeal-item-info-left-value item-style">{{item.Address}}</text>
</view>
</view>
</view>
</view>
<mp-loading wx:if="{{!finishedLoading}}" class="loading-style" type="dot-gray" show="{{loading}}"></mp-loading>
<text wx:else class="loading-txt">已经到底了...</text>
</scroll-view>
</view>
<view wx:else class="nodatab {{currentStatus == 0? '': 'lazyload-p'}}">
<text>暂无内容</text>
</view>
</view>
lazyr.wxss
.work{
margin-top: 0rpx;
height: 100vh;
background-color: lightgray;
}
.work-header{
width: 100%;
height: 120rpx;
position: fixed;
z-index: 1000;
float: left;
top: 0rpx;
left: 0;
background-color: red;
padding: 19rpx 40rpx 4rpx 40rpx;
}
.work-header-t{
width: 100%;
height: 120rpx;
}
.lazyload{
height: 100% !important;
width: 100%;
padding-bottom: calc(env(safe-area-inset-bottom) / 2);
}
/* 基本信息 */
.undeal-item{
width: 100%;
height: 240rpx;
margin-top: 10rpx;
background-color: #fff;
}
.undeal-item-info{
padding: 0 26rpx 0rpx 38rpx;
display: flex;
flex-direction: column;
}
.undeal-item-info-oneline,
.undeal-item-info-twoline{
margin-top: 16rpx ;
font-size: 22rpx;
display: flex;
justify-content: space-between;
}
.undeal-item-info-oneline{
color: #237AE4;
}
.undeal-item-info-left{
flex: 1;
display: flex;
}
.undeal-item-info-right{
flex: 1;
display: flex;
}
.undeal-item-info-left-label{
width: 110rpx;
}
.undeal-item-info-right-label{
width: 120rpx;
}
.undeal-item-info-left-value,
.undeal-item-info-right-value{
justify-content: flex-end;
}
.item-label-style{
color: #666;
}
.item-style{
color: #333;
}
/* loading样式 */
.loading-style{
display: block;
padding-top: 40rpx;
padding-bottom: 40rpx;
}
.loading-txt{
font-size: 20rpx;
padding-bottom: 10rpx;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
color: #666;
background-color: lightgray;
}