首页 > 不确定图片高度情况下,如何实现瀑布流布局?

不确定图片高度情况下,如何实现瀑布流布局?

很多情况下,带图片的列表,在不能确定每一个item高度的情况下,如何实现瀑布流?每一个item的高度不一定,也不一样高(图片还会因网络延时而出现高度变化的情况)


两种方式:
1,item使用绝对定位的;例子:
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>瀑布流</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="container">
    <div class="box">
        <div class="box-img">
            <img src="img1.jpg" alt="pic1">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="img2.jpg" alt="pic2">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="img3.jpg" alt="pic3">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="img4.jpg" alt="pic4">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="img5.jpg" alt="pic5">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="img6.jpg" alt="pic6">
        </div>
    </div>
</div>
</body>
</html>

CSS:

*{margin: 0;padding: 0;}
.container{position: relative;width: 1040px;margin: 0 auto;}
.box{float: left;padding: 5px;font-size: 0;}
.box-img img{width: 250px;}

JQ:

$(function(){
    var elesHeight = [];//每个元素的宽度
    var colsHeight = [0,0,0,0]; //每列元素现有的高度
    $(".container .box").each(function(index,item){
        var eleHeight = $(this).height();
        elesHeight.push(eleHeight);
    });

    //依次摆放每一个元素
    $(".container .box").each(function(index,item){

        //获得该元素应该在第几列
        var colShould = getMinHeightCol(colsHeight);

        var tempTop = colsHeight[colShould];
        var tempLeft = colShould*260;
        $(this).css({"position":"absolute","top":tempTop+"px",left:tempLeft+"px"});

        //同时将该列的高度加上当前新增元素的高度
        colsHeight[colShould] += $(this).height();
    });

    //得到四列中高度最小的那一列
    function getMinHeightCol(arr){
        var minHeight = Math.min.apply(null, arr);
        console.log("最小高度:"+minHeight);
        for(var i in arr){
            if(arr[i]==minHeight){
                return i;
            }
        }
        //默认第一列
        return 0;
    }
    var re;
    window.onresize = function() {
      clearTimeout(re);
      re = setTimeout(resize,100); 
    };
});

2:item所显示图片为缩略图,缩略图生成后高度存储到数据库,前端生成页面时,写到img的style="height:XXXX"即可;但是文字内容么~~~~只能固定高度了;

更新下,丢人了,少些了高度两字被人嘘了;骚瑞哦~


由于时间的原因,我先做了临时的解决方案:@golden_freeman_china的优化方案

3列布局:用bootstrap列布局搭建好盒子

<div class="row layout-box">
    <div class="col-xs-4 layout-itme"></div>
    <div class="col-xs-4 layout-itme"></div>
    <div class="col-xs-4 layout-itme"></div>
</div>

js实现

Array.prototype.min = function() {
    var min = { key: 0, val: this[0] };
    for (var i = 0; i < this.length; i++) {
        if (this[i] < min.val) {
            min = {
                key: i,
                val: this[i]
            }
        }
    }
    return min;
}
function setHeight(data) {
    //去除第几条数据
    var index = 0;
    //可以不阻塞后面的代码执行,可以延时判断列布局高度
    var timer = setInterval(function() {
        //保存三列布局的高度数值
        var arr = [];
        //获取三列盒子
        var boxs = document.querySelectorAll('#layout-box .layout-item');
        //获取每一列高度
        for (var i = 0; i < boxs.length; i++) {
            var realStyle = window.getComputedStyle(boxs[i], null).height;
            //不适用parseInt转换,获取到的将是数字形式的字符串,不能使用arr.min进行判断最小值
            arr.push(parseInt(realStyle.match(/\d+/)[0]));
        }
        //得到哪一列的高度最小
        var key = arr.min().key;

        var div = document.createElement('div');
        //将html给div,用于appendChild到boxs中
        div.innerHTML = data[index].content;
        //给高度最小的那一列添加子元素
        boxs[key].appendChild(div);
        //保证data中所有内容都被添加到页面
        if (index < data.length - 1) {
            index++;
        } else {
            clearInterval(timer);
        }
    }, 0)
}

ajax(url,function(data){
    /*//ajax返回的数据列表
    var data = [
        {
            content:"<img src=''/>",
        },
        {
            content:"<img src=''/>",
        },
        {
            content:"<img src=''/>",
        },
    ];*/
    setHeight(data);
})

缺陷:图片加载非常慢时仍然会出现三列高度差距过大的问题,定时器时差不要超过30ms,否则会有人为的卡顿效果(或者加上渐入效果可以解决这个问题)


方案2:
纯css3实现多列布局:column-count,column-gap,column-rule

缺陷:

  1. 必须给每一个item设置display:inline-block,其实就是把item盒子当成一个个的文字进行排版

  2. 在box中新增item后,每一列都会重新布局,体验超差,根本不知道自己浏览到了哪里,又新增了那些


方案3:
使用现有jquery的layout插件,绝对定位每一个元素,这样出现的问题就是,图片加载前已经定位布局好,图片加载后,下面的item就会盖着上面的,直观的就是所有item叠加在一起


imagesLoaded插件,用来监视图片加载,加载完成触发事件然后布局。
其实就是给每个添加的图片监视onload事件。


看一下waterful 插件。。

【热门文章】
【热门文章】