瀑布流的原理与实现,包含改进过程


注:本文部分图片自百度下载,如有侵权,联系删图。

瀑布流的实现

首先,选择几张图片布局到HTML内容中。HTML如下所示。

 <div class="wrapper">
        <div class="item"><img src="img/1.jpg" height="auto"/></div>
        <div class="item"><img src="img/2.jpg" height="auto"/></div>
        <div class="item"><img src="img/3.jpg" height="auto"/></div>
        <div class="item"><img src="img/4.jpg" height="auto"/></div>
        <div class="item"><img src="img/5.jpg" height="auto"/></div>
        <div class="item"><img src="img/6.jpg" height="auto"/></div>
        <div class="item"><img src="img/7.jpg" height="auto"/></div>
        <div class="item"><img src="img/8.jpg" height="auto"/></div>
        <div class="item"><img src="img/9.jpg" height="auto"/></div>
        <div class="item"><img src="img/10.jpg" height="auto"/></div>
        <div class="item"><img src="img/11.jpg" height="auto"/></div>
        <div class="item"><img src="img/12.jpg" height="auto"/></div>
        <div class="item"><img src="img/13.jpg" height="auto"/></div>
        <div class="item"><img src="img/14.jpg" height="auto"/></div>
        <div class="item"><img src="img/15.jpg" height="auto"/></div>
    </div>

纯CSS实现

纯CSS实现较为简单,主要代码为设置列数和间距的两行。

/* 将边距设为0 */
*{
    margin: 0;
    padding: 0;
    border: none;
}

.wrapper{
    width: auto;
    height: auto;
    position: relative;
    margin: 0 auto;
    /* 设置列数和间距 */
    column-count: 4;
    column-gap: 0;
}
.item{
    position:relative;
    width: 100%;
    height: auto;
    box-sizing: border-box;
    padding: 2px;
}

.item img{
    display: block;
    width: 100%;
    cursor: pointer;
    border-radius: 5px;
}
.item img:hover{
    opacity: 0.8;
}

结果如图所示:
在这里插入图片描述

Jquery实现

  1. 有bug的实现
    定义一个瀑布流方法:
 function waterfall(element,child,padding) {
    var child = $(child) || $('.item');
    var wrap = $(element) || $('.wrapper');
    var padding = padding || 25;

    // 宽度,所有元素宽度一致
    var itemW=$(".item").outerWidth(true);

   //  可容纳总列数
    var colNum=Math.floor(wrap.outerWidth(true)/child.outerWidth(true));
    console.log(colNum);//3

   //  初始化第一列的top和left值
    var posi=new Array(colNum);

    $.each(posi,(i)=>{
        posi[i]=new Object();
        posi[i].top = padding;
        posi[i].left = padding + i * itemW;

    })
     
    //  每个元素所处列数
    var eleCol=[];
     //循环图片列表
    child.each(function (i) {
        
        if ((i+1)% colNum == 0) {
            eleCol[i] = colNum;
        }else{
            eleCol[i] = (i+1) % colNum;
        }
        var sub = eleCol[i]-1;
        var top = posi[sub].top+'px';
        var left = posi[sub].left+'px';
       //  设置每个元素的位置
        $(this).css({"position":"absolute","top" :top,"left" : left});
       //  每遍历完一次,重置top值
       posi[sub].top += $(this).outerHeight(true);

    })
}

该方法原理图如图所示:

在这里插入图片描述

这是按照顺序,根据上行图片大小对定位加以调整的方式布局的。

但是,这种方法会造成空行。如图:

在这里插入图片描述

这是由于第一列某张图片过于大的缘故。

因此,在做瀑布流时,应该根据已布局好的元素的高度进行剩余元素的布局。就是说,比如第一行元素已经布局完成,第二行元素应该先选择第一行元素中,高度最小的那个元素所在列进行插入。这样,才能保证不会出现某一列太长或者某一列过短的现象。

  1. 根据以上分析,我们得到,实现瀑布流的核心其实是,找出图片高度最小的一列,并在此插入图片

改进后的瀑布流方法:

function waterfall(element,child) {
    var child = $(child) || $('.item');
    var wrap = $(element) || $('.wrapper');

    // 宽度,所有元素宽度一致
    var itemW=$(".item").outerWidth(true);

   //  可容纳总列数
    var colNum=Math.floor(wrap.outerWidth(true)/child.outerWidth(true));
    console.log(colNum);//3

    
    // 定义列高度数组并初始化
    var itemH = new Array(colNum);
    $.each(itemH,(i)=>{
        itemH[i]=0;
    })


     //循环图片列表
    child.each(function (i) {  
        // 定义最小高度和对应的index并初始化
        var minHeight = itemH[0];
        var minIndex = 0;
        console.log("最初最小高度为:"+minHeight+"下标为:"+minIndex);

        // 存储本次循环对象的高度
        var thisH = $(this).outerHeight(true);

        $.each(itemH,(i)=>{
            if (itemH[i] < minHeight) {
                minHeight = itemH[i];
                minIndex = i;
            }
            console.log("比较后最小高度为:"+minHeight+"下标为:"+minIndex);
        })
 

        var sub = minIndex;
        var top = minHeight;
        var left = minIndex * itemW;
       //  设置每个元素的位置
        $(this).css({"position":"absolute","top" :top,"left" : left});
       //  每遍历完一次,重置列高度值
       itemH[sub] += thisH;
       console.log("itemH值:"+itemH[sub]);

    })
}

如图所示:
在这里插入图片描述
代码实现链接:
https://github.com/jiujiu12/web-practice/tree/master/瀑布流实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值