瀑布流的实现方式,移动端的瀑布流,数据多列表渲染方式

18 篇文章 0 订阅

效果请看:链接
代码请看:链接

问题:

在H5的移动端开发中,经常会遇到类似瀑布流的布局,近期做了一下总结。
大致有三种实现方式:
1. css3的column属性实现
2. jquery,对高做数组处理的定位型方式
3. js,对高做数组处理的定位型方式

一、先说在工作中的实例,及制作方式

实例,在工作中,我们会用到视频列表,UI如下:
瀑布流实例图片1
瀑布流实例图片2

1、 css3实现

废话不多说,直接上代码:

.listContent {
    column-count: 2;
    -webkit-column-count: 2;
    -o-column-count: 2;
    -ms-column-count: 2;
    -moz-column-count: 2;

    column-gap: 1px;
    -webkit-column-gap: 1px;
    -o-column-gap: 1px;
    -ms-column-gap: 1px;
    -moz-column-gap: 1px;
}
.listContent li {
    width: 4.98rem;
}
#videoList .listContent li{
    padding-bottom: 0.06666667rem;
    margin: 0;
    background: #e8e8e8;
}

<div class="bottomVideoList clearfix">                  
    <ul class="listContent clearfix"></ul>
</div>

注意
1. 在列表的父元素设置,列数column-count;在子元素li中设置宽度
2. 它应该有默认的缝隙,对于移动端来说有点大,然后就需要自己设置列之间的缝隙column-gap值
3. 还有个问题是,子元素li不能设置margin,会影响计算,只能设置padding

2.用两列ul来处理(比较笨)

在数据渲染的时候,由于图片高度不同,首先要预加载图片,然后再进行渲染,渲染的时候计算ul的高度,根据高度小的ul,向上添加li

/*预加载图片的方法*/
var loadImg = function(src, callback) {
    var oScript = new Image();
    oScript.src = src;
    oScript.onload = function() {
        if(typeof(callback) == "function") {
            callback();
        } else {
            return
        }
    }
}
/*HTML*/
<div class="bottomVideoList clearfix">
    <div class="TVS fl myTvs">
        <ul class="listContent clearfix">
        </ul>
    </div>
    <div class="TVS fr hotTvs">
        <ul class="listContent clearfix">
        </ul>
    </div>
</div>


/*数据渲染的方法*/
var dataList = res.data.list;
var num = 0;
var flagLoad = false;
for(var i = 0; i < dataList.length; i++) {
    var videopic = dataList[i].videopic;
    /*做图片的预加载*/
    loadImg(videopic, function() {
        num++;
        if(num < dataList.length) return;
        if(flagLoad) {
            flagLoad = false;
            /*如果有图片打不开,则走不到这一步*/
            for(var j = 0; j < dataList.length; j++) {
                var thatLi = document.createElement('li');
                str = '拼接字符串';
                $(thatLi).append(str);
                var height1 = $('.myTvs').height();
                var height2 = $('.hotTvs').height();
                if(height2 < height1) {
                    $('.hotTvs .listContent').append(thatLi);
                } else {
                    $('.myTvs .listContent').append(thatLi);
                }
            }
        }
    })
}
3.使用瀑布流思维:根据高度数组做定位
二、瀑布流的三种实现方式
  • 1.css3,column-count、column-width、column-gap三者结合的方式
column-count: 2;
-webkit-column-count: 2;
-o-column-count: 2;
-ms-column-count: 2;
-moz-column-count: 2;

column-width: 100px;
-webkit-column-width: 100px;
-o-column-width: 100px;
-ms-column-width: 100px;
-moz-column-width: 100px;

column-gap: 1px;
-webkit-column-gap: 1px;
-o-column-gap: 1px;
-ms-column-gap: 1px;
-moz-column-gap: 1px;
  • 2.jquery

    先渲染数据,再对子元素进行定位

/*HTML*/
<div id="main">
    <div class="pin">
        <div class="box">
            <img src="./images/1.jpg"/>
        </div>
    </div>
    <div class="pin">
        <div class="box">
            <img src="./images/2.jpg"/>
        </div>
    </div>
</div>
/* js */
//首先加载数据,并渲染上去
$.each( dataInt.data, function( index, value ){
    var $oPin = $('<div>').addClass('pin').appendTo( $( "#main" ) );
    var $oBox = $('<div>').addClass('box').appendTo( $oPin );
    $('<img>').attr('src','./images/' + $( value).attr( 'src') ).appendTo($oBox);
});
//再进行样式的修整
waterfall();

function waterfall(parent,pin){
    var $aPin = $( "#main>div" );
    var iPinW = $aPin.eq( 0 ).width();// 一个块框pin的宽
    var num = Math.floor( $( window ).width() / iPinW );//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
    //设置父级居中样式:定宽+自动水平外边距
    $( "#main" ).css({
        'width:' : iPinW * num,
        'margin': '0 auto'
    });

    var pinHArr=[];//用于存储 每列中的所有块框相加的高度。

    $aPin.each( function( index, value ){
        var pinH = $aPin.eq( index ).height();
        if( index < num ){
            pinHArr[ index ] = pinH; //第一行中的num个块框pin 先添加进数组pinHArr
        }else{
            var minH = Math.min.apply( null, pinHArr );//数组pinHArr中的最小值minH
            var minHIndex = $.inArray( minH, pinHArr );
            $( value ).css({
                'position': 'absolute',
                'top': minH + 15,
                'left': $aPin.eq( minHIndex ).position().left
            });
            //数组 最小高元素的高 + 添加上的aPin[i]块框高
            pinHArr[ minHIndex ] += $aPin.eq( index ).height() + 15;//更新添加了块框后的列高
        }
    });
}
  • 2.js

    原理与jquery一样,先渲染数据,再对子元素进行定位

var oParent = document.getElementById('main');// 父级对象
for(var i=0;i<dataInt.data.length;i++){
    var oPin=document.createElement('div'); //添加 元素节点
    oPin.className='pin';                   //添加 类名 name属性
    oParent.appendChild(oPin);              //添加 子节点
    var oBox=document.createElement('div');
    oBox.className='box';
    oPin.appendChild(oBox);
    var oImg=document.createElement('img');
    oImg.src='./images/'+dataInt.data[i].src;
    oBox.appendChild(oImg);
}
waterfall('main','pin');


function waterfall(parent,pin){
    var oParent=document.getElementById(parent);// 父级对象
    var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin
    var iPinW=aPin[0].offsetWidth;// 一个块框pin的宽
    var num=Math.floor(document.documentElement.clientWidth/iPinW);//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
    oParent.style.cssText='width:'+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距

    var pinHArr=[];//用于存储 每列中的所有块框相加的高度。
    for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素
        var pinH=aPin[i].offsetHeight;
        if(i<num){
            pinHArr[i]=pinH; //第一行中的num个块框pin 先添加进数组pinHArr
        }else{
            var minH=Math.min.apply(null,pinHArr);//数组pinHArr中的最小值minH
            var minHIndex=getminHIndex(pinHArr,minH);
            aPin[i].style.position='absolute';//设置绝对位移
            aPin[i].style.top=minH+'px';
            aPin[i].style.left=aPin[minHIndex].offsetLeft+'px';
            //数组 最小高元素的高 + 添加上的aPin[i]块框高
            pinHArr[minHIndex]+=aPin[i].offsetHeight;//更新添加了块框后的列高
        }
    }
}

function getminHIndex(arr,minH){
    for(var i in arr){
        if(arr[i]==minH){
            return i;
        }
    }
}

效果请看:链接
代码请看:链接

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值