web頁面和小程序頁面實現瀑布流效果

  小程序實現瀑布流效果,和web頁面差很少,都要通過如下步驟:javascript

1)、加載圖片,獲取圖片的寬高度;css

2)、根據頁面須要顯示幾列計算每列的寬度;html

3)、根據圖片真實寬度和每列的寬度比,計算出圖片須要顯示的高度;java

4)、從新對圖片進行定位git

 

  一、web頁面瀑布流效果,先看效果圖(瀑布流+無限滾動加載):github

 頁面代碼:web

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
        <meta charset=’utf-8′> <!--聲明文檔使用的字符編碼-->
        <title>瀑布流_左浮動</title>
    <style type="text/css">
        *{margin:0;padding:0;}
        .container {
            width: 1200px; height: auto; margin: 50px auto;
            position: relative;
        }
        .box{
            padding: 5px; box-shadow: 0 0 10px purple; border-radius: 5px;
            float: left; margin: 10px;
        }
        .box img { width: 200px; height: auto; }
    </style>
</head>
<body>
    <div class="container">
        <div class="box"><img src="../img/0.jpg"/></div>
        <div class="box"><img src="../img/1.jpg"/></div>
        <div class="box"><img src="../img/2.jpg"/></div>
        <div class="box"><img src="../img/3.jpg"/></div>
        <div class="box"><img src="../img/4.jpg"/></div>
        <div class="box"><img src="../img/5.jpg"/></div>
        <div class="box"><img src="../img/6.jpg"/></div>
        <div class="box"><img src="../img/7.jpg"/></div>
        <div class="box"><img src="../img/8.jpg"/></div>
        <div class="box"><img src="../img/9.jpg"/></div>
        <div class="box"><img src="../img/10.jpg"/></div>
        <div class="box"><img src="../img/11.jpg"/></div>
        <div class="box"><img src="../img/12.jpg"/></div>
        <div class="box"><img src="../img/13.jpg"/></div>
        <div class="box"><img src="../img/14.jpg"/></div>
        <div class="box"><img src="../img/15.jpg"/></div>
        <div class="box"><img src="../img/16.jpg"/></div>
    </div>
    <script type="text/javascript">

        var boxsHeight = []; //盒子高度存儲數組
        var boxWidth = 230, boxHeight = 230;
        window.onload = function(){

            var boxs = document.getElementsByClassName('box');
            var cols = Math.floor(1200.0/boxWidth); //最多幾列

            //offsetWidth: 包括元素的內容寬度+padding+border寬度
            //存儲第一行的每一個盒子的高度到數組裏面
            for (var i = 0; i < cols; i++){
                var obj = boxs[i]; //元素節點

                if (i < cols){
                    boxsHeight.push(obj.offsetHeight);
                }
            }

            updateBoxFrame(cols);  //從第二行開始更新元素的位置

            window.onscroll = pageScroll;  //設置頁面滾動監聽函數

            pageScroll();  //先調用一次
        }

        //獲取數組中最小值的索引
        function getMinHeightIndex(arr){
            var minHeight = Math.min.apply(null, arr);

            for (var i = 0; i < arr.length; i++){
                if (arr[i] == minHeight){
                    return i;
                }
            }
        }

        //監聽頁面滾動
        function pageScroll(){

            var parentEle = document.getElementsByClassName('container')[0];
            var subEleCount = parentEle.childElementCount; //子元素個數
            var lastBox = parentEle.lastElementChild; //最後一個元素

            //判斷是否滾動到底部
            var doc = document.documentElement||document.body;

            console.log('滾動監聽', doc.scrollTop+",", lastBox.offsetTop+", " + doc.clientHeight);

            if (doc.scrollTop+doc.clientHeight > lastBox.offsetTop){
                //表示該新添加元素了
                addBox();
                //更新新添加元素的位置
                updateBoxFrame(subEleCount);
            }

        }

        //新添加子元素
        function addBox(){

            var parentEle = document.getElementsByClassName('container')[0];

            var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
            for (var i = 0; i < arr.length; i++){

                var index = parseInt(Math.random()*100%arr.length);
                var imgNum = arr[index];
                var div = document.createElement('div');
                div.setAttribute('class', 'box');
                div.innerHTML = '<img src="../img/' + imgNum + '.jpg"/>'
                parentEle.appendChild(div);

                arr.splice(index, 1)
            }
        }

        //更新新添加元素的位置
        function updateBoxFrame(startIndex){

            var boxs = document.getElementsByClassName('box');

            for (var i = startIndex; i < boxs.length; i++){
                var obj = boxs[i];
                //獲取數組中最小高度的索引
                var minHeightIndex = getMinHeightIndex(boxsHeight);
//                    console.log(boxsHeight);
//                    console.log(minHeightIndex + ", " +boxsHeight[minHeightIndex]);
                var boxTop = boxsHeight[minHeightIndex] + 20;
                var boxLeft = minHeightIndex * boxWidth;

                console.log(i + ', boxTop: ' + boxTop + ", boxLeft: " + boxLeft);

                //設置元素的定位樣式
                obj.style = 'position: absolute; top:' + boxTop + "px;left:" + boxLeft+"px";
                boxsHeight[minHeightIndex] = boxTop + obj.offsetHeight;
            }

        }

    </script>
</body>
</html>
View Code

 

  二、小程序實現瀑布流,大體流程差很少。只不太小程序的圖片的寬高度的獲取沒有web頁面那麼方便。小程序

大概實現過程:1)、獲取圖片數據,頁面渲染;數組

      2)、給圖片綁定加載load事件,存儲每一個圖片的寬高度;app

      3)、計算每一個圖片的定位,從新渲染

  

先看小程序的效果圖(瀑布流+無限循環加載):

wxml頁面代碼:

<scroll-view class='main' scroll-y='true' style="height:{{windowHeight}}px" bindscrolltolower='loadMoreImages'>
    <image wx:for='{{dataList}}' wx:key='item' src='{{item.src}}' style='position: absolute; top: {{item.top}}px; left: {{item.left}}px; width: {{imgWidth}}px; height: {{item.height}}px' bindload='loadImage' data-index='{{index}}' bindtap='previewImg'/>
</scroll-view>
View Code

js頁面代碼:

// pages/discover/waterfall_flow/waterfall_flow.js
Page({

  /**
   * 頁面的初始數據
   */
  data: {
    dataList: [], //數據源
    windowWidth: 0, //頁面視圖寬度
    windowHeight: 0, //視圖高度
    imgMargin: 6, //圖片邊距: 單位px
    imgWidth: 0,  //圖片寬度: 單位px
    topArr: [0, 0], //存儲每列的累積top
  },

  /**
   * 生命週期函數--監聽頁面加載
   */
  onLoad: function (options) {

    wx.showLoading({
      title: '加載中...',
    })
    var that = this;
    //獲取頁面寬高度
    wx.getSystemInfo({
      success: function (res) {
        console.log(res)

        var windowWidth = res.windowWidth;
        var imgMargin = that.data.imgMargin;
        //兩列,每列的圖片寬度
        var imgWidth = (windowWidth - imgMargin * 3) / 2;

        that.setData({
          windowWidth: windowWidth,
          windowHeight: res.windowHeight,
          imgWidth: imgWidth
        }, function () {
          that.loadMoreImages(); //初始化數據
        });
      },
    })
  },
  //加載圖片
  loadImage: function (e) {

    var index = e.currentTarget.dataset.index; //圖片所在索引
    var imgW = e.detail.width, imgH = e.detail.height; //圖片實際寬度和高度
    var imgWidth = this.data.imgWidth; //圖片寬度
    var imgScaleH = imgWidth / imgW * imgH; //計算圖片應該顯示的高度

    var dataList = this.data.dataList;
    var margin = this.data.imgMargin;  //圖片間距
    //第一列的累積top,和第二列的累積top
    var firtColH = this.data.topArr[0], secondColH = this.data.topArr[1];
    var obj = dataList[index];

    obj.height = imgScaleH;

    if (firtColH < secondColH) { //表示新圖片應該放到第一列
      obj.left = margin;
      obj.top = firtColH + margin;
      firtColH += margin + obj.height;
    }
    else { //放到第二列
      obj.left = margin * 2 + imgWidth;
      obj.top = secondColH + margin;
      secondColH += margin + obj.height;
    }

    this.setData({
      dataList: dataList,
      topArr: [firtColH, secondColH],
    });
  },
  //加載更多圖片
  loadMoreImages: function () {
    var imgs = [
      'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1409185525,4059560780&fm=26&gp=0.jpg',
      'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4076355782,2436939971&fm=15&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=777075993,2126273204&fm=11&gp=0.jpg',
      'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=57777155,3251523579&fm=11&gp=0.jpg',
      'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3825727093,2830650732&fm=11&gp=0.jpg',
      'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2379065095,654347953&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2749679283,2472217536&fm=11&gp=0.jpg',
      'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=677128138,409184861&fm=11&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1884091074,3049103326&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1600363417,3661952978&fm=11&gp=0.jpg',
      'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2069544162,3090555174&fm=11&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3328655038,3143543956&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3953624046,2332872335&fm=26&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=717009955,687560133&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4243037288,2388509769&fm=26&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2644451528,4180971732&fm=26&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2658655215,924706045&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=400545645,1325440240&fm=26&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2735743532,3162562682&fm=11&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2357555025,1781222560&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1604156508,3282489713&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=380663325,2271064034&fm=26&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=174537541,3462862985&fm=26&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1752649241,364583051&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2890516059,4166188770&fm=27&gp=0.jpg',
      'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2435144503,200941795&fm=11&gp=0.jpg',
      'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=877833827,2847590581&fm=26&gp=0.jpg',
      'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=894452177,2810600152&fm=11&gp=0.jpg',
      'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4053642431,248486335&fm=27&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2914607659,905736210&fm=11&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1629456501,1514429218&fm=26&gp=0.jpg',
    ];

    var tmpArr = [];
    for (let i = 0; i < 22; i++) {
      var index = parseInt(Math.random() * 100) % imgs.length;
      var obj = {
        src: imgs[index],
        height: 0,
        top: 0,
        left: 0,
      }
      tmpArr.push(obj);
      imgs.splice(index, 1);
    }

    var dataList = this.data.dataList.concat(tmpArr)
    this.setData({ dataList: dataList }, function(){
      wx.hideLoading()
    });
  },
  /**預覽圖片 */
  previewImg: function (e) {

    var index = e.currentTarget.dataset.index;
    var dataList = this.data.dataList;
    var currentSrc = dataList[index].src;
    // var srcArr = dataList.map(function (item) {
    //   return item.src;
    // });

    wx.previewImage({
      urls: [currentSrc],
    })
  },


})
View Code

wxss頁面代碼:

.main{ width: 100%; height: 100%; position: relative; }
.main image {
  box-shadow: 0 0 10rpx red; border-radius: 8rpx;
}
View Code

 

DEMO下載:https://github.com/xiaotanit/Tan_HtmlDemo

web瀑布流頁面地址:https://github.com/xiaotanit/Tan_HtmlDemo/blob/master/JS/%E7%80%91%E5%B8%83%E6%B5%81_%E5%B7%A6%E6%B5%AE%E5%8A%A8.html

小程序瀑布流頁面地址:https://github.com/xiaotanit/Tan_HtmlDemo/tree/master/wxMini/pages/discover/waterfall_flow

 

個人博客即將同步至騰訊雲+社區,邀請你們一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=130g6z2h5r49d

相關文章
相關標籤/搜索