微信ウィジェットで滝のレイアウトと無限のロードを実現

5254 ワード

滝流レイアウトは比較的流行しているページレイアウト方式であり、最も典型的なのはPinterestである.comは、カードごとに高さが異なり、バラツキのある美しさを形成しています.
HTML 5では、jQueryのような実装に基づく滝流レイアウトプラグインを多く見つけることができ、このようなレイアウト形式を簡単に作ることができます.微信小プログラムでは、このような効果も得ることができますが、小プログラムのフレームワークのいくつかの特性のため、実現の構想にはいくつかの違いがあります.
今日は、小さなプログラムでこのような滝のレイアウトを実現する方法を見てみましょう.
小プログラム滝流レイアウト
固定2列のレイアウトを実現し、この2列にピクチャデータを動的にロードします(ロードされたピクチャは、ピクチャの実際のサイズに応じて、左列に置くか右列に置くかを決定します).
/*           */
.img_item {
  width: 48%;
  margin: 1%;
  display: inline-block;
  vertical-align: top;
}

HTMLでは、画像を動的にロードする場合、new Image()を使用して画像オブジェクトを作成し、urlが指す画像を動的にロードし、画像の実際のサイズなどの情報を取得することがよく知られています.ウィジェットフレームワークでは,対応するJSオブジェクトはピクチャロードを処理するために提供されていない.実はwxmlのコンポーネントを借りてこのような機能を完成することができて、少し回りますが、しかしやはり私たちの機能の要求を満たすことができます.


  


Pageでは、wxmlにロードするピクチャ情報をデータバインドにより伝達し、コンポーネントにピクチャリソースをロードさせ、ピクチャロードが完了したときにbindloadで指定されたイベント処理関数によりさらに処理することができる.
Pageファイルで定義されているonImageLoad関数を見てみましょう.ここで、入力されたイベントオブジェクトeから、コンポーネントの実際のサイズを含む豊富な情報を取得することができる.次に,画像をページに実際に表示する必要がある寸法に従って,同比例スケーリング後の寸法を算出する.次に,左右の2列の現在蓄積されているコンテンツの高さに基づいて,現在ロードされているピクチャをどちらに置くかを決定することができる.
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;  //       
        let scale = imgWidth / oImgW;        //    
        let imgHeight = oImgH * scale;      //     

        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;

        //               
        if (col1H <= col2H) {
            col1H += imgHeight;
            col1.push(imageObj);
        } else {
            col2H += imgHeight;
            col2.push(imageObj);
        }

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

        //           ,              
        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
        });
    }

})

ここでは、2列のピクチャに表示されるwxmlコードです.コンポーネントにbindscrolltoolowerを使用してイベントリスニング関数を設定し、最後までスクロールするとloadImagesが次のピクチャデータのセットを再ロードするようにトリガーされ、無制限のロードが形成されます.

  
    
      
        
      
    
    
      
        
      
    
  


はい、簡単な例ですが、もっと良い方法があれば、共有してください.
完全なコードは私のGithubでダウンロードできます.https://github.com/zarknight/wx-falls-layout