OK,
我们接到上一篇瀑布流的实现,下面我们来讲讲不固定列的实现瀑布流
像花瓣网,百度图片的实现方式一样。
根据调整窗口也就是可视区的大小来改变显示图片的列数。同时也有个运动的效果。
实现原理:
布局:有一个容器,为相对定位,里面的img为绝对定位。
数据添加:因为每张图片的宽度是固定的,高度是不固定的。所以我们先要算出可视区的宽度能放下几列图片,然后在算出每列图片的高度,由高度最低的那列在添加下一张图片,我们用一张图片来形象说明下:
这一种实现可谓是最优的一种方案,方便添加数据内容,窗口变化,列数会自动调整。
OK那么下面就给出实现的代码吧,用jquery来实现的。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>瀑布流</title>
<style>
* {margin: 0; padding: 0;}
#container { width: 1000px; border: 1px solid red; position: relative; margin: 50px auto 0; }
#container img { position: absolute; }
#loader { width: 100%; height: 60px; background: url('loader.gif') no-repeat center #FFF; position: fixed; bottom: 0; left: 0; display: none; }
</style>
<script src="jquery-1.9.1.min.js"></script>
<script>
/*
不固定列:定位
根据可视区调整列数(非固定列数)
怎么添加数据的呢,每列图片添加好之后,在算出每列的高度,下一张图片添加到高度最低的那一列的下面。
*/
$(function() {
//计算列
var oContainer = $('#container');
var oLoader = $('#loader');
var iCells = 0;//总列
var iWidth = 200;//每列宽度
var iSpace = 10;//间隔宽
var iOuterWidth = iWidth + iSpace;//实际列宽
var sUrl = 'http://www.wookmark.com/api/json/popular?callback=?';
var arrT = [];
var arrL = [];
var iPage = 0;//一开始加载第一页的数据
var iBtn = true;
function setCell() {//计算可视区有多少列
iCells = Math.floor($(window).innerWidth() / iOuterWidth);
//列数固定在3到6列之间,避免列数太多太卡。
if (iCells < 3) {
iCells = 3;
} else if (iCells > 6) {
iCells = 6;
}
//alert(iCells);
oContainer.css('width', iCells * iOuterWidth) - 10;//占位宽度
}
setCell();
for (var i=0; i<iCells; i++) {
arrT[i] = 0;
arrL[i] = iOuterWidth * i;
}
//console.log(iCells);
//console.log(arrL);
function getData() {
if (!iBtn) {
return ;
}
iBtn = false;
iPage++;//加载一批显示一批
oLoader.show();//数据加载完成之前显示转圈loading
$.getJSON(sUrl, {page:iPage}, function(jData) {
//$('#loader').show();
$.each(jData, function(index, obj) {//循环数据
var oImg = $('<img />');
//宽高
var iHeight = obj.height * (iWidth / obj.width);
oImg.css({
width : iWidth,
height : iHeight
});
//获取arrT最小值的位置
var _index = getMin();
//设置定位
oImg.css({
left : arrL[_index],
top : arrT[_index]
});
arrT[_index] += iHeight + 10;
oContainer.append(oImg);
var objImg = new Image();
objImg.onload = function() {
oImg.attr('src', this.src);
}
objImg.src = obj.preview;
/*setTimeout(function() {
$('#loader').hide();
},1000)*/
iBtn = true;
oLoader.hide();//数据加载完成之后隐藏转圈loading
})
});
}
getData();//初始化的时候调用一次
//arrT = [11,23,5,7];
//获取数据中最小值的位置
function getMin() {
var v = arrT[0];
var _index = 0;
for (var i=1; i<arrT.length; i++) {
if (arrT[i] < v) {
v = arrT[i];
_index = i;
}
}
return _index;
}
//alert(getMin());
//滚动条的滚动事件
$(window).on('scroll', function() {
var _index =getMin();
var iH = $(window).scrollTop() + $(window).innerHeight();
//document.title = iH + ':' + (arrT[_index] + oContainer.offset().top);
if (arrT[_index] + oContainer.offset().top < iH) {
//alert(1);
iPage++;
getData();
}
})
$(window).on('resize', function() {
var iLen = iCells;
setCell();
if (iLen == iCells) {
return ;
}
arrT = [];
arrL = [];
for (var i=0; i<iCells; i++) {
arrT[i] = 0;
arrL[i] = iOuterWidth * i;
}
oContainer.find('img').each(function() {
var _index = getMin();
/*$(this).css({
left : arrL[_index],
top : arrT[_index]
});*/
$(this).animate({
left : arrL[_index],
top : arrT[_index]
}, 1000);
arrT[_index] += $(this).height() + 10;
});
})
})
</script>
</head>
<body>
<div id="container"></div>
<div id="loader"></div>
</body>
</html>
可以复制代码到本地试试体验效果如何
不错就给赞吧!