返回首页 | 注册送体验金88送现金

合作共赢、快速高效、优质的网站建设提供商

更多精品源码-尽在织梦模板-www.moke8.com

[编码]微信小程序下瀑布流加载解决方案

时间:2017-08-03 编辑:admin

1、什么是瀑布流

1.1、瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,图片的宽度是固定的,高度自动。视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。

2、h5下实现一个瀑布流的基本思路 2.1、定义基本的html结构
 div 
 div 
 img src="" alt="" 
 /div 
 div 
 img src="" alt="" 
 /div 
 /div 
2.2、定义基本的css样式
.container{
.container{width: 100%;padding: 10px 10px;position: relative;}
.list{float: left;width: 100px;padding: 10px;bottom: 10px;}
.list img{width: 100px;}
2.3、js动态计算加载项的样式。
function water_fall(parent_selector,box_selector){
 let boxElem=document.getElementsByClassName(box_selector);
 let boxWidth=boxElem[0].offsetWidth;
 let cols=2;
 let height_arr=[];
 for(let i=0;i boxElem.length;i++){
 let cur_box=boxElem[i];
 let cur_box_height=cur_box.offsetHeight;
 if(i cols){
 height_arr.push(cur_box_height);
 }else{
 let minH = Math.min.apply(null, height_arr);
 let index=height_arr.indexOf(minH);
 cur_box.style.cssText+=`;position: absolute;top:${minH}px;left:${boxWidth*index}px`;
 height_arr[index]+=cur_box_height;
 var maxH = Math.max.apply(null, height_arr);
 let parentElem=document.getElementById(parent_selector);
 parentElem.style.cssText+=`;height: ${maxH}px`;
}

这里固定2列,通过定义一个高度数组,然后遍历区块,获取每个列表项的高度,然后push到数组,从数组中找到最短的高度所在的位置来决定后面的列表加入到哪一列,并且设置它的left和top。到此一个简单的瀑布流已经完成,上面的代码其实还可以优化。每次只需遍历新加载的数据,然后追加到父节点中。

3、如何在微信小程序下实现一个瀑布流。

说了这么多,其实无非是想接下来做一个对比,来看下微信小程序下怎么实现一个瀑布流。
还是分3步
3.1、定义基本的wxml结构

 view 
 view 
 image src="***"/ 
 /view 
 /view 

3.2、定义基本的wxss样式

.content_list{position: relative;}
.img_item{width: 100%;}
.list{width: 350rpx;min-height: 200rpx;}

这里有个差别,就是我没有给.list这个class设置padding了,因为在微信小程序下是不能够操作节点获取样式的。
后面我们将根据图片的宽度动态计算左右两边以及左边一列图片的padding。同时这里图片的单位用的是rpx。主要是为了适应不同屏幕终端。
3.3、js动态计算加载项的样式。
两种方案,第一种定义一个隐藏域,用于存放图片,当图片加载的时候绑定加载事件获取图片的宽高

 view 
 image wx:for="{{temImgArr}}" wx:key="id" id="{{item.id}}" binderror="onImageError" src="https:{{item.link}}" bindload="onImageLoad" /image 
 /view 

主要js代码如下:

onImageLoad: function (e) {
 let imageId = e.currentTarget.id;
 let oImgW = e.detail.width; //图片原始宽度
 let oImgH = e.detail.height; //图片原始高度
 let imgWidth = (this.data.winWidth - 20) * 0.48;
 let scale = imgWidth / oImgW; //比例计算
 let imgHeight = scale * oImgH;
 let imgObj = {
 id: imageId,
 width: imgWidth,
 height: imgHeight
 imgLen++;
 for (let i = 0; i temResImgArr.length; i++) {
 if (temResImgArr[i].id == imageId) {
 temResImgArr[i].width = imgWidth;
 temResImgArr[i].height = imgHeight;
 break;
 if (imgLen == temResImgArr.length) {//图片遍历完
 this.waterFall();
 onImageError: function (e) {
 imgLen++;
 waterFall: function () {
 for (let i = 0; i temResImgArr.length; i++) {
 if (heightArr.length 2 i 2) {
 heightArr.push(temResImgArr[i].height + 10);
 } else {
 let minH = Math.min.apply(null, heightArr);
 let index = heightArr.indexOf(minH);
 temResImgArr[i].top = `${minH}`;
 temResImgArr[i].left = `${360 * index}rpx`;
 heightArr[index] += (temResImgArr[i].height + 10);
 let maxH = Math.max.apply(null, heightArr);
 let temp = this.data.imgArr;
 temp.push(...temResImgArr);
 this.setData({
 imgArr: temp,
 viewHeight: maxH,
 temImgArr: []
 //重置数据。
 temResImgArr = [];
 imgLen = 0;
 wx.hideToast();
 },

但是这种方案并不是最优,需要定义2个临时数组来处理加载的图片,同时用户等待的时间太长,必须要等所有图片加载完后获取到所有的高度后才能够展示出来,体验很不好。
既然花了大部分时间在获取图片宽高上面,那么为什么不能够从接口输出图片宽高呢?
所以要么上传图片的时候把宽高录入db,但是这种并没有什么意义。要么就是输出的时候处理,这时想到了PHP有个getimagesize函数(PHP是世界上最好的语言有木有),可以获取到图片的宽高。这样就不用改db了。
且看改进后的js代码:

 onLoad: function () {
 let self = this;
 imgLen = 0;
 heightArr = [];
 wx.getSystemInfo({
 success: function (res) {
 let imgW = Math.floor(350 * (res.windowWidth) / 750);//图片在当前屏幕尺寸下的实际宽度
 let colW = Math.floor((res.windowWidth - 2 * imgW) / 3);//左右两边边距和图片边距的宽度
 self.setData({
 winWidth: res.windowWidth,
 winHeight: res.windowHeight,
 colW: colW,
 self.getImgInfo();
waterFall: function (data) {
 let j = 0;
 for (let i = 0; i data.length; i++) {//遍历动态加载的数据
 let imgW = Math.floor(350 * this.data.winWidth / 750);//获取图片在当前屏幕下的实际宽度
 data[i].height = Math.floor(imgW * data[i].height / data[i].width);
 if (heightArr.length 2 i 2) {
 heightArr.push(data[i].height + this.data.colW);//实际高度+动态边距
 data[i].top = `0`;
 data[i].left = i == 0 ? `${imgW * i + this.data.colW}` : `${imgW * i + 2 * this.data.colW}`;
 } else {
 let minH = Math.min.apply(null, heightArr);
 let index = heightArr.indexOf(minH);
 data[i].top = `${minH}`;
 data[i].left = index == 0 ? `${imgW * index + this.data.colW}` : `${imgW * index + 2 * this.data.colW}`;
 heightArr[index] += (data[i].height + this.data.colW);
 let maxH = Math.max.apply(null, heightArr);
 let temp = this.data.imgArr;
 temp.push(...data);//追加到当前图片列表中
 this.setData({
 imgArr: temp,
 viewHeight: maxH,
 //重置数据。
 imgLen = 0;
 wx.hideToast();
 },

这样就实现了一个微信小程序下的瀑布流。实际效果可以打开微信,扫描左边二维码,直接体验。
PS:无双不成对,一张图太单调,请容许我再附上最近做的一款美的砍价小程序,美的认证,砍到即可购买。最近天气热,有购买家电的朋友可以
浏览:

网站建设

流程

    网站建设流程