在微信小程序中,有2个事件,相信大家都很熟悉
下拉重新加载
上拉加载更多
事件是这么个事件,至于事件触发后干嘛,那就看代码了
首先要在对应得地方xxxxpage.json打开这个
"onReachBottomDistance": 100
至于这个值100还是多少要看你的实际情况,为了不让用户看到默认的框框啥的,应该是设置大一些!
xxxpage.js中
onReachBottom(){
//组件的class="lazyimage"
var child =this.selectComponent('.lazyimage');
if(child){
child.onScrollIndex();//告知懒加载组件,触发了上拉触底事件
}else{
console.log(this);
}
}
然后就是我们的组件代码了 比如命名为lazyimage
lazyimage.js
// components/goodsParse/goodsParse.js
Component({
/**
* 组件的属性列表
*/
properties: {
parseData: {
type: Array,
value: []
},
param: {
type: String
},
scrollindex:{
type:Number,
value:0,
default:0
},
lazyload:{
type:Boolean,
value:false
}
},
/**
* 组件的初始数据
*/
data: {
imageCount: 0,
imagedatas:[],
loadcount:0,
current_load_height:0,//本次渲染的图片的总高度 如果本次渲染的总高度不足1500 则会再次渲染per_load_count
current_loaded_ok:false,//本次是否渲染完成
per_load_min_height:1500,//每次至少渲染多少高度
per_load_count:3//每次渲染的张数,如果渲染的总高度不足,会继续渲染
},
/**
* 组件的方法列表
*/
methods: {
handleImgtap() {
},
onImageLoad(e) {
this.data.imageCount ++
//又不用渲染UI 所以下面的代码没必要
// this.setData({
// imageCount: this.data.imageCount
// })
if(e.detail){
if(e.detail.height){
//本张图片渲染的高度
this.data.current_load_height+=e.detail.height;
}
}
if(this.data.lazyload){
//本次懒加载的图片已经加载完成了
if(this.data.imageCount == this.data.loadcount){
this.data.current_loaded_ok=true;
this.triggerEvent('onImageLoad', this.data.imageCount);
//未完待续 如果还可以继续加载,如果刚刚加载的总高度小于屏幕的总高度,则继续贪婪加载
if(this.data.current_load_height<this.data.per_load_min_height){
//本次渲染的高度太小了,看看是否可以继续渲染,再次渲染3张
this.loadNext(this.data.per_load_count);
}
}
}else{
//非懒加载
if(this.data.imageCount == this.data.imagedatas.length){
this.triggerEvent('onImageLoad', this.data.imageCount);
}
}
//如果渲染不够,还可以继续渲染
// console.log(e);//可以通过e来计算本次加载是否足够,不够的话补足剩余的数量
},
loadNext(num){
if(this.data.loadcount<this.data.imagedatas.length){
//渲染接下来的N个?
var _max = this.data.imagedatas.length;
if(this.data.loadcount<(_max)){
this.data.current_load_height=0;
var _temptop = Math.min(this.data.loadcount+num,(_max));
// console.log('loadcount',this.data.loadcount,'images',this.data.imagedatas.length,'temp',_temptop);
if(_temptop>this.data.loadcount){
var _new_array=new Array();
var _datas =this.data.imagedatas;
for(var k=this.data.loadcount;k<_temptop;k++){
if(this.data.imagedatas.length>k){
_new_array.push(
{
vkey:'imagedatas['+k+'].src',
src:_datas[k].presrc
}
);
}
}
if(_new_array.length>0){
var _obj={};
for(var ii of _new_array){
_obj[ii.vkey]=ii.src
}
this.setData(_obj);
// console.log('set new images src!');
}
this.data.loadcount = _temptop;
}
}
}
},
onScrollIndex(){
//这个函数是给外部调用的,一般发生在上拉触底(要基于实际去设定这个高度值)的时候
if(this.data.imagedatas.length ==this.data.loadcount){
// console.log('已经全部完成渲染,无法继续执行更多的懒加载');
//已经全部懒加载完成,不需要继续加载了
return;
}
if(!this.data.current_loaded_ok){
// console.log('上一次的渲染未完成··· ·· ·');
return;
}
// console.log('parent`s scroll-view scroll to lower!');
if(this.data.imageCount<this.data.loadcount){
// console.log('之前加载的图片还未完全加载完成');
return;
}
this.loadNext(this.data.per_load_count);
},
requireLoadAll(){
//父级页面要求加载全部
if(this.data.loadcount != this.data.imagedatas.length){
var _n = this.data.imagedatas.length-this.data.loadcount;
if(_n>0){
if(!this.data.current_loaded_ok){
// console.log('上一次的渲染未完成··· ·· ·');
return;
}
// console.log('parent`s scroll-view scroll to lower!');
if(this.data.imageCount<this.data.loadcount){
// console.log('之前加载的图片还未完全加载完成');
return;
}
this.loadNext(_n);
}
}
}
},
attached(){
// console.log('load goods-parse attached!');
var _lazyload=this.data.lazyload;
if(this.data.parseData!=null && this.data.parseData.length>0){
var _imgarray=new Array();
var _i =0;
for(var img of this.data.parseData){
_i ++;
if(_i<= this.data.per_load_count || !_lazyload){
_imgarray.push({
src:img,
presrc:img
});
}else{
_imgarray.push({
src:null,
presrc:img
});
}
}
this.data.loadcount =this.data.per_load_count;//当前有渲染的序号
this.setData({
imagedatas:_imgarray
});
console.log(_imgarray);
}
}
})
对应的lazyimage.wxml代码如下(这个看你的实际情况修改)
<view class="parse_box">
<block >
<view class="u-padding-top-10" style="font-size:0px;">
<block wx:if="{{parseData}}">
<view>
<block wx:for="{{imagedatas}}" wx:for-item="item" wx:for-index="index" wx:key="index">
<block wx:if="{{item.src}}">
<image class="parse_image" src="{{item.src}}" mode="widthFix" bindload="onImageLoad" binderror="onImageLoad"/>
</block>
</block>
</view>
</block>
</view>
</block>
</view>
至于样式就不贴了!
这个组件适用于单图横向100vw的模式,比如商品的图片列表纵向显示
关键点在于
图片数据是parseData
比如:
[“https://xxx.jpg”,“https://xxx.jpg”]
转化成imagedatas
比如
[{
presrc:“”,
src:null
}]
除了一开始的数量设置src为对应的图片地址,后面的都是设置null
然后在上拉触底事件触发的时候,再把后面的图片对象设置src=presrc!
然后就是高度的判断,有可能比如你配置每次加载3张图,如果这三张图的高度不够一屏,那体验上用户就能看到图片还在加载了!
所以代码上做了一个贪婪模式,就是图片load后,去计算本次加载的总高度,是否满足,不够的话再多懒加载一次!
看函数代码
onImageLoad(e) {
this.data.imageCount ++
//又不用渲染UI 所以下面的代码没必要
// this.setData({
// imageCount: this.data.imageCount
// })
if(e.detail){
if(e.detail.height){
//本张图片渲染的高度
this.data.current_load_height+=e.detail.height;
}
}
if(this.data.lazyload){
//本次懒加载的图片已经加载完成了
if(this.data.imageCount == this.data.loadcount){
this.data.current_loaded_ok=true;
this.triggerEvent('onImageLoad', this.data.imageCount);
//未完待续 如果还可以继续加载,如果刚刚加载的总高度小于屏幕的总高度,则继续贪婪加载
if(this.data.current_load_height<this.data.per_load_min_height){
//本次渲染的高度太小了,看看是否可以继续渲染,再次渲染3张
this.loadNext(this.data.per_load_count);
}
}
}else{
//非懒加载
if(this.data.imageCount == this.data.imagedatas.length){
this.triggerEvent('onImageLoad', this.data.imageCount);
}
}
//如果渲染不够,还可以继续渲染
// console.log(e);//可以通过e来计算本次加载是否足够,不够的话补足剩余的数量
},