zoukankan      html  css  js  c++  java
  • web页面和小程序页面实现瀑布流效果

      小程序实现瀑布流效果,和web页面差不多,都要经过以下步骤:

    1)、加载图片,获取图片的宽高度;

    2)、根据页面需要显示几列计算每列的宽度;

    3)、根据图片真实宽度和每列的宽度比,计算出图片需要显示的高度;

    4)、重新对图片进行定位

      1、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

      2、小程序实现瀑布流,大致流程差不多。只不过小程序的图片的宽高度的获取没有web页面那么方便。

    大概实现过程:1)、获取图片数据,页面渲染;

          2)、给图片绑定加载load事件,存储每个图片的宽高度;

          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;  {{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

  • 相关阅读:
    ZooKeeper的安装和API
    Flume案例Ganglia监控
    二十五、小程序的图片预览(放大滑动)
    二十四、小程序中改变checkbox和radio的样式
    二十三、小程序中的三级下拉框(下拉菜单)
    二十二:制作app的时候超出部分不能滑动
    二十一、当锚点遇到fixed(margin和padding)
    二十:让行内元素在div中垂直居中
    十九、多文件上传(ajaxFileupload实现多文件上传功能)
    十六、字符串和数组之间的转换
  • 原文地址:https://www.cnblogs.com/tandaxia/p/9703312.html
Copyright © 2011-2022 走看看