小程序模板網(wǎng)

一斤代碼:微信小程序中實(shí)現(xiàn)瀑布流布局和無限加載

發(fā)布時(shí)間:2018-03-30 16:19 所屬欄目:小程序開發(fā)教程

瀑布流布局是一種比較流行的頁面布局方式,最典型的就是Pinterest.com,每個(gè)卡片的高度不都一樣,形成一種參差不齊的美感。

在HTML5中,我們可以找到很多基于jQuery之類實(shí)現(xiàn)的瀑布流布局插件,輕松做出這樣的布局形式。在微信小程序中,我們也可以做出這樣的效果,不過由于小程序框架的一些特性,在實(shí)現(xiàn)思路上還是有一些差別的。

今天我們就來看一下如何在小程序中去實(shí)現(xiàn)這種瀑布流布局:

我們要實(shí)現(xiàn)的是一個(gè)固定2列的布局,然后將圖片數(shù)據(jù)動(dòng)態(tài)加載進(jìn)這兩列中(而加載進(jìn)來的圖片,會(huì)根據(jù)圖片實(shí)際的尺寸,來決定到底是放在左列還是右列中)。


					
/* 單個(gè)圖片容器的樣式 */
.img_item {
  width: 48%;
  margin: 1%;
  display: inline-block;
  vertical-align: top;
}

我們知道,在HTML中,我們要?jiǎng)討B(tài)加載圖片的話,通常會(huì)使用new Image()創(chuàng)建一個(gè)圖片對象,然后通過它來動(dòng)態(tài)加載一個(gè)url指向的圖片,并獲取圖片的實(shí)際尺寸等信息。而在小程序框架中,并沒有提供相應(yīng)的JS對象來處理圖片加載。其實(shí)我們可以借助wxml中的組件來完成這樣的功能,雖然有點(diǎn)繞,但還是能滿足我們的功能要求的。


					
<!-- 在頁面上放一個(gè)隱藏區(qū)域,并用image組件去加載一個(gè)或多個(gè)圖片資源 -->
<view style="display:none">
  <image wx:for="{{images}}" wx:key="id" id="{{item.id}}" src="{{item.pic}}" bindload="onImageLoad"></image>
</view>

我們可以在Page中通過數(shù)據(jù)綁定,來傳遞要加載的圖片信息到wxml中,讓組件去加載圖片資源,然后當(dāng)圖片加載完成的時(shí)候,通過bindload指定的事件處理函數(shù)來做進(jìn)一步處理。

我們來看一下Page文件中定義的onImageLoad函數(shù)。在其中,我們可以從傳入的事件對象e上,獲取到組件的豐富信息,包括通過它加載進(jìn)來的圖片的實(shí)際大小。然后我們將圖片按照頁面上實(shí)際需要顯示的尺寸,計(jì)算出同比例縮放后的尺寸。接著,我們可以根據(jù)左右兩列目前累積的內(nèi)容高度,來決定把當(dāng)前加載進(jìn)來的圖片放到哪一邊。


					
let col1H = 0;
let col2H = 0;

Page({

    data: {
        scrollH: 0,
        imgWidth: 0,
        loadingCount: 0,
        images: [],
        col1: [],
        col2: []
    },

    onLoad: function () {
        wx.getSystemInfo({
            success: (res) => {
                let ww = res.windowWidth;
                let wh = res.windowHeight;
                let imgWidth = ww * 0.48;
                let scrollH = wh;

                this.setData({
                    scrollH: scrollH,
                    imgWidth: imgWidth
                });

                //加載首組圖片
                this.loadImages();
            }
        })
    },

    onImageLoad: function (e) {
        let imageId = e.currentTarget.id;
        let oImgW = e.detail.width;         //圖片原始寬度
        let oImgH = e.detail.height;        //圖片原始高度
        let imgWidth = this.data.imgWidth;  //圖片設(shè)置的寬度
        let scale = imgWidth / oImgW;        //比例計(jì)算
        let imgHeight = oImgH * scale;      //自適應(yīng)高度

        let images = this.data.images;
        let imageObj = null;

        for (let i = 0; i < images.length; i++) {
            let img = images[i];
            if (img.id === imageId) {
                imageObj = img;
                break;
            }
        }

        imageObj.height = imgHeight;

        let loadingCount = this.data.loadingCount - 1;
        let col1 = this.data.col1;
        let col2 = this.data.col2;

        //判斷當(dāng)前圖片添加到左列還是右列
        if (col1H <= col2H) {
            col1H += imgHeight;
            col1.push(imageObj);
        } else {
            col2H += imgHeight;
            col2.push(imageObj);
        }

        let data = {
            loadingCount: loadingCount,
            col1: col1,
            col2: col2
        };

        //當(dāng)前這組圖片已加載完畢,則清空圖片臨時(shí)加載區(qū)域的內(nèi)容
        if (!loadingCount) {
            data.images = [];
        }

        this.setData(data);
    },

    loadImages: function () {
        let images = [
            { pic: "../../images/1.png", height: 0 },
            { pic: "../../images/2.png", height: 0 },
            { pic: "../../images/3.png", height: 0 },
            { pic: "../../images/4.png", height: 0 },
            { pic: "../../images/5.png", height: 0 },
            { pic: "../../images/6.png", height: 0 },
            { pic: "../../images/7.png", height: 0 },
            { pic: "../../images/8.png", height: 0 },
            { pic: "../../images/9.png", height: 0 },
            { pic: "../../images/10.png", height: 0 },
            { pic: "../../images/11.png", height: 0 },
            { pic: "../../images/12.png", height: 0 },
            { pic: "../../images/13.png", height: 0 },
            { pic: "../../images/14.png", height: 0 }
        ];

        let baseId = "img-" + (+new Date());

        for (let i = 0; i < images.length; i++) {
            images[i].id = baseId + "-" + i;
        }

        this.setData({
            loadingCount: images.length,
            images: images
        });
    }

})

這里是顯示在兩列圖片的wxml代碼,我們可以看到在組件上,我們通過使用bindscrolltolower設(shè)置了事件監(jiān)聽函數(shù),當(dāng)滾動(dòng)到底部的時(shí)候,會(huì)觸發(fā)loadImages去再加載下一組的圖片數(shù)據(jù),這樣就形成了無限的加載:


					
<scroll-view scroll-y="true" style="height:{{scrollH}}px" bindscrolltolower="loadImages">
  <view style="width:100%">
    <view class="img_item">
      <view wx:for="{{col1}}" wx:key="id">
        <image src="{{item.pic}}" style="width:100%;height:{{item.height}}px"></image>
      </view>
    </view>
    <view class="img_item">
      <view wx:for="{{col2}}" wx:key="id">
        <image src="{{item.pic}}" style="width:100%;height:{{item.height}}px"></image>
      </view>
    </view>
  </view>
</scroll-view>

好了,挺簡單的一個(gè)例子,如果你有更好的方法,不吝分享一下哦。


 
 
 


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://m.u-renovate.com/wxmini/doc/course/22989.html 復(fù)制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢
AI智能客服 ×