瀑布流的實現方式,移動端的瀑布流,資料多列表渲染方式
阿新 • • 發佈:2019-01-02
問題:
在H5的移動端開發中,經常會遇到類似瀑布流的佈局,近期做了一下總結。
大致有三種實現方式:
1. css3的column屬性實現
2. jquery,對高做陣列處理的定位型方式
3. js,對高做陣列處理的定位型方式
一、先說在工作中的例項,及製作方式
例項,在工作中,我們會用到視訊列表,UI如下:
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;
}
}
}