虚拟列表——无限滚动
在做项目的过程中有一个列表页会产生非常多的数据,列表会变得卡顿 于是问了度娘一遍说了两种情况
- 等高列表
- 不等高列表
我这里要讲的是第二种不等高列表,而且是动态加载数据 以下是实现大致的显示效果
如果实现呢?上代码 wxml代码
<scroll-view class="lsmap" id="screenSee" scroll-y bindscrolltolower="bindscrolltolower" bindscroll="bindscroll">
<view style="height: {{ headerHeight }}px;"></view>
<view wx:for="{{pageList}}" wx:if="{{item.visible}}" wx:key="index" id="listPageId{{index}}">
<faqsItem canCtl="{{false}}" wx:for="{{item.data}}" wx:key="id" wx:for-item="qItem"
wx:for-index="qIndex" bind:ctlClick="showCtlModal" bind:getPhoneNumber="itemGetPhoneNumber" phone="{{phone}}"
accessToken="{{accessToken}}" itemData="{{qItem}}" data-item="{{qItem}}" data-index="{{index}}"
data-qindex="{{qIndex}}">
</faqsItem>
</view>
<view style=" height: {{bottomHeight}}px;"></view>
<empty isEmpty="{{isEmpty}}" noMore="{{noMore}}"></empty>
</scroll-view>
js代码
Page({
/**
* 页面的初始数据
*/
data: {
current: 1,
size: 10,
content: '',
newsLs: [],//文章列表
isLoading: false,//加载中
isEmpty: false,//空
noMore: false,//没有更多
headerHeight: 0,
bottomHeight: 0,
pageList: [// 每一页数据
// {
// data: [],//数据
// visible: false,// 当前是否显示
// }
],
pageHeight: [// 每一页高度
// {
// top: 0, // 顶部在scroll里的高度
// height: 0, // 高度
// bottom:0, // 底部在scroll里的高度
// }
],
scrollH: 0,// 滚动框高度
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
this.getListData();
const query = wx.createSelectorQuery();
query.select('#screenSee').boundingClientRect().exec((res) => {
this.setData({
scrollH: res[0].height
})
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
// 滚动触底
bindscrolltolower() {
if (!this.data.noMore) {
this.getListData()
}
},
// 滚动
bindscroll(e) {
// 实现虚拟列表
let pageList = this.data.pageList, headerHeight = this.data.headerHeight, bottomHeight = this.data.bottomHeight;
this.data.pageHeight.forEach((item, index) => {
// 手指上滑
if (e.detail.deltaY < 0 && item.bottom < floatObj.subtract(e.detail.scrollTop, 10) && pageList[index].visible && pageList[index + 2]) {
// 隐藏头部
pageList[index].visible = false;
headerHeight += item.height;
// 显示底部
if (!pageList[index + 2].visible) {
pageList[index + 2].visible = true;
bottomHeight -= this.data.pageHeight[index + 2].height
}
this.setData({
pageList: pageList,
headerHeight: headerHeight,
bottomHeight: bottomHeight
})
}
// 手指下滑
if (e.detail.deltaY > 0 && item.top > floatObj.add(e.detail.scrollTop, floatObj.add(this.data.scrollH, 10)) && pageList[index].visible == true && pageList[index - 2]) {
// 隐藏头部
pageList[index].visible = false;
bottomHeight += item.height;
if (!pageList[index - 2].visible) {
// 显示底部
pageList[index - 2].visible = true;
headerHeight -= this.data.pageHeight[index - 2].height
}
this.setData({
pageList: pageList,
headerHeight: headerHeight,
bottomHeight: bottomHeight
})
}
})
},
// 搜索输入
searchInput(e) {
this.setData({
content: e.detail.value,
})
},
// 搜索
getListData() {
if (this.data.isLoading) return
// 获取列表数据
getqList().then(res => {
if (res.code == 200) {
let tampParam = {}
let tempLs = res.data.records.map(el => {
if (el.content) {
el.content = JSON.parse(el.content)
} else {
el.content = []
}
return el
});
if (res.data.records.length < this.data.size) {
tampParam = {
current: this.data.current + 1,
isEmpty: this.data.current == 1 && res.data.records.length == 0 ? true : false,
noMore: true,
newsLs: this.data.newsLs.concat(res.data.records)
}
} else {
tampParam = {
current: this.data.current + 1,
newsLs: this.data.newsLs.concat(res.data.records)
}
}
if (res.data.records.length > 0) {
let pageList = this.data.pageList, pageHeight = this.data.pageHeight;
pageList.push({
data: res.data.records,//数据
visible: true,// 当前是否显示
})
pageHeight.push({
top: 0, // 顶部在scroll里的高度
height: this.data.virtualHeight, // 高度
bottom: this.data.virtualHeight, // 底部在scroll里的高度
})
tampParam.pageList = pageList
tampParam.pageHeight = pageHeight
}
this.setData(tampParam)
if (res.data.records.length > 0) {
setTimeout(() => {
this.initPageHeight(this.data.current - 2)
}, 0);
}
}
})
},
// 初始化首页高度
initPageHeight(index) {
const query = wx.createSelectorQuery();
query.select(`#listPageId${index}`).boundingClientRect().exec((res) => {
let pageHeight = this.data.pageHeight;
pageHeight[index] = {
top: index > 0 ? pageHeight[index - 1].bottom + 1 : 0, // 顶部在scroll里的高度
height: res[0].height,
bottom: index > 0 ?
floatObj.add(pageHeight[index - 1].bottom + 1, res[0].height)
: res[0].height, // 底部在scroll里的高度
}
this.setData({
pageHeight: pageHeight
})
})
},
})
这里是部分代码。需要源代码请关注公众号 ”BWeb“或者扫下方二维码,然后回复 ”微信小程序虚拟列表“