1:js 两列布局实现,思路:左右分为两个容器,根据容器的高度(相对低的那一个)决定下一个元素应该放在哪个容器内,这样视觉就实现了瀑布流的效果,代码如下:
- 瀑布流容器
js代码
//接口获取数据,循环展示
function forList(list){
var HTML = "";
for(var i=0;i' ;
HTML+='' ;
HTML+=''+list[i].sTitle+'';
HTML+= '';
HTML+= '';
}
/**
* HTML ;拼接后的字符串
* #box,存放瀑布流的容器
*/
// 调用瀑布流函数
warterfall(HTML,'#box')
}
//拉取数据
forList(lists1);
// 瀑布流函数
function warterfall(HTML,content) {
//生成左右两个容器及暂时存放元素的容器(hidebox)
if($(content+' ul').length<=0){
$(content).append('
');
}
//数据先放在一个隐藏的容器,
$("#hidebox").html(HTML);
//取出元素
var items=$("#hidebox li");
//获取左右两个容器
var leftbox=$(content+' .left');
var rightbox=$(content+' .right');
//设置延迟,保证图片加载完成,避免影响左右容器高度的计算,导致数据放到错误的位置
setTimeout(function () {
// 左边容器高度
var leftDivHeight = leftbox.height();
// 右边容器高度
var rightDivHeight =rightbox.height();
items.each(function (index,item) {
//瀑布流函数,该函数计算左右容器的总高度,决定把下一个元素放在哪个容器里面
//获取左右容器高度
leftDivHeight = leftbox.height();
rightDivHeight = rightbox.height();
//把下一个元素放在高度低的容器里面
if(leftDivHeight<=rightDivHeight) {
leftbox.append(item);
return;
}
rightbox.append(item);
})
},500)
};
效果如下:
2:js position定位,思路:js记录左右两列的所有元素并计算总高度,决定下一个元素的放置位置(注意:元素与元素之间不能用margin
,因为这样会影响定位)代码如下:
- 瀑布流容器
js代码
function warterfall(parent, box) {
//瀑布流函数,该函数将图片定位到上一行高度最小图片下方,接数据,更新dom后,重新执行该函数
//将main下的所有class为box的元素取出来
var oParent = $('#'+parent);
var oBoxs =oParent.find('.'+box);
//计算整个页面显示的列数(页面宽/box的宽);
var oBoxW = oBoxs.eq(0).width();
var cols = 2;
var hArr = [];
for (var i = 0; i < oBoxs.length; i++) {
var currentBox=oBoxs.eq(i);
if (i < cols) {
// 将前2张图片的宽度记录到hArr数组中(第一行的高度)
hArr.push(currentBox.height());
} else {
//从第二行开始就开始找最小的高度了,决定待插入图片该插入到哪里
// 找到高度最小的值
var minH = hArr[0]>hArr[1]?hArr[1]:hArr[0];
var index = hArr.indexOf(minH);
// 设置最小高度的图片的style为绝对定位,并设置top和left
currentBox.css({
'position':'absolute',
'top': minH ,
'left': oBoxW * index
});
//高度叠加
hArr[index] += currentBox.height();
}
}
};
function forList(list){
var HTML = "";
for(var i=0;i' ;
HTML+='' ;
HTML+=''+list[i].sTitle+'';
HTML+= '';
HTML+= '';
}
$("#content").append(HTML);
setTimeout(function(){
warterfall("content", "item");
},3000)
}
forList(lists1);
$(".btn").on('click',function () {
forList(lists1)
})
效果如下:
完美实现,但是它每次都需要获取全部元素,再重新定位,很耗性能。
3: css
实现
页面布局:
加载更多
样式设置
.box{
width: 100%;
height: 600px;
overflow: scroll;
}
.box .force-column {
width: 100%;
position: relative;
overflow-x: hidden;
/*设置元素分几列显示*/
-moz-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
}
.box-item{
width: 200px;
background: yellowgreen;
}
img{
width: 200px;
height: auto;
}
假如数据是接口返回的
-
打开页面写,效果如下:
效果虽然实现了,但是美中不足的是,他有个问题:数据不是按照1-2-3-4,的顺序来排列的,而是左边是1,3,5,右边是2,4,6。对于需要展示的数据对排序有要求的话(比如排行榜),此种方法不合适;如何来解决这个bug,很简单,就是我们需要对数据进行二次处理,把1,3,5数据放在前面,2,4,6f放在后面,这样就可以了,代码如下:
//数据处理1,3,5,放前面,2,4,6放后面
function dataFilter(lists){
var leftArr=[];
var rightArr=[];
$.each(lists,function (index,value) {
if(index%2==0) {
leftArr.push(value)
}else {
rightArr.push(value)
}
})
var currentArr= [].concat(leftArr,rightArr);
return currentArr
}
forList(dataFilter(lists))
效果如下:
-
,此时数据看起来是按照顺序排列的,并且均分放置,也就是两列的列表个数几乎是一样的,但是如果两边的数据因为文字或者图片差异比较大,是否会导致两列高度差异比较大的问题呢?,我们来修改数据看一下,比如增加一些文字,效果如下:
此时看到的结果是:即使两列数据不同,不会导致两列的高度差异很大,因为根据高度差,数据的排列已经发生了改变,比如,第7个列表笨应该放在第一列的最后,现在因为两边高度的问题,而自动放在了第2列的第一位,也就是我们之前的担心是多余的,系统已经做了处理,但是这样的实现方式,还是有我们之前顾虑的问题,就是对数据的排列有要求的需求,这种方法是不适合的。