欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

web页面和小程序页面实现瀑布流效果

程序员文章站 2022-06-05 16:10:12
小程序实现瀑布流效果,和web页面差不多,都要经过以下步骤: 1)、加载图片,获取图片的宽高度; 2)、根据页面需要显示几列计算每列的宽度; 3)、根据图片真实宽度和每列的宽度比,计算出图片需要显示的高度; 4)、重新对图片进行定位 1、web页面瀑布流效果,先看效果图(瀑布流+无限滚动加载): 页 ......

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

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

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

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

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

 

  1、web页面瀑布流效果,先看效果图(瀑布流+无限滚动加载):

web页面和小程序页面实现瀑布流效果

 页面代码:

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)、计算每个图片的定位,重新渲染

  

先看小程序的效果图(瀑布流+无限循环加载):

web页面和小程序页面实现瀑布流效果

wxml页面代码:

web页面和小程序页面实现瀑布流效果
<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页面代码:

web页面和小程序页面实现瀑布流效果
// 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页面代码:

web页面和小程序页面实现瀑布流效果
.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

 

版权声明


作者:tdx

出处:博客园tdx的技术博客--http://www.cnblogs.com/tandaxia

您的支持是对博主最大的鼓励,感谢您的认真阅读。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

我的博客即将同步至腾讯云+社区,邀请大家一同入驻: