资讯专栏INFORMATION COLUMN

微信小程序下瀑布流加载解决方案

AlphaWatch / 1195人阅读

摘要:实际效果如下这样就实现了一个微信小程序下的瀑布流。实际效果可以打开微信,扫描左边二维码,直接体验。或者微信小程序搜索拍照大全。

1、什么是瀑布流

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

2、h5下实现一个瀑布流的基本思路 2.1、定义基本的html结构

3.2、定义基本的wxss样式

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

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

    
        
    

主要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了。
备注:这里更正下,组内大神一眼就看出输出时候用getimagesize函数处理存在性能问题,就是高并发的时候、服务器带宽很容易耗尽,不同进程之间拉取同样图片还无法利用缓存。最后还是改为将图片宽高存入后台。
且看改进后的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,
        });
        //重置数据。
        temp=null;
        imgLen = 0;
        wx.hideToast();
    },

实际效果如下:

这样就实现了一个微信小程序下的瀑布流。实际效果可以打开微信,扫描左边二维码,直接体验。或者微信小程序搜索拍照POSE大全。里面附很多美图,各种拍照姿势等你来完善,来补充,欢迎体验并上传自己的小姿势。
PS:无双不成对,一张图太单调,请容许我再附上最近做的一款美的砍价小程序,美的认证,砍到即可购买。最近天气热,有购买家电的朋友可以扫码购买。

最后,如果你有更优的解决方案请告诉我,我们一起探讨,欢迎点评!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25559.html

相关文章

  • 信小程序瀑布加载解决方案

    摘要:实际效果如下这样就实现了一个微信小程序下的瀑布流。实际效果可以打开微信,扫描左边二维码,直接体验。或者微信小程序搜索拍照大全。 1、什么是瀑布流 1.1、瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,图片的宽度是固定的,高度自动。视觉表现为参差不齐的多列布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。 2、h5下实现一个瀑布流的基本思路 2.1、定义...

    kumfo 评论0 收藏0
  • 原生js实现瀑布信小程序中使用左右两列实现瀑布

    摘要:使用实现瀑布流并不实用,因为实现的瀑布流都是以列来排列的,这里记录下用实现瀑布流,以及微信小程序中使用左右两列来实现瀑布流效果图原生实现瀑布流文件图片可以自己找点替换下就可以了文件添加阴影的时候,加上会显得更加有点悬浮感文件计算图片列数 使用css实现瀑布流并不实用,因为css实现的瀑布流都是以列来排列的,这里记录下用js实现瀑布流,以及微信小程序中使用左右两列来实现瀑布流 1.效果图...

    imingyu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<