用position: absolute布局,然后计算top,left
首先,将容器分成几列,记录高度
往最矮的列添加一个item
以上的都是很简单的实现思想,而今天的重点是item涉及图片的时候,或者有懒加载情况下的瀑布流。
因为在这样的情况下,item的高度可能是不定的,因为加载图片的高度是不定的,于是怎么样获取item的高度就是一个难题
最简单的方法就是后台传输数据
我参考了一下,花瓣网 http://huaban.com/ 它的做法是这样的
服务器访问页面的时候,把几个文件拼接输出(根据我的观察有(1)公用页面(2)系统配置(3)引入的js(4)页面数据(5)页面收尾)
在(4)页面数据中,他就有了图片的宽高,跟一系列可以拼接成一个item的数据。在加载的时候,根据这些初始数据加载输出,其中图片的大小符合某种比例的话就有最大高度的限制,不然图片就按照图片高度输出
以下的是我没有控制图片高度的一个瀑布流实现代码
var waterfall = (function(){
// console.clear();
waterfall();
function waterfall(id) {
var id = id || ‘app-content-scroll‘;
var parentlist = $(‘.‘ + id);
parentlist.each(function() {
var count = 0;
var parent = $(this);
var timer = setInterval(function(){
if(parent.children(‘section‘).length > 0) {
// 现在有一个小小的bug
// 就是图片没有加载完的时候,高度是会变的
// 这会造成对这个元素的预估失准
// 打算在懒加载上面做图片的高度赋值
var wf = new WaterFall(parent);
$(window).bind(‘resize‘,function() {
wf.col = Math.floor($(parent).width() / (wf.wid + wf.spa)) - 1;
wf.init();
});
wf.parent.children(‘section‘).css(‘transition‘, ‘all 0.2s ease‘);
clearTimeout(timer);
} else if(count > 100) {
clearTimeout(timer);
}
count++;
},100);
});
}
function WaterFall(parent) {
this.parent = parent;
this.child = parent.children(‘section‘);
this.spa = 15;
// 空元素
this.col = 0;
this.wid = 0;
this.colLen = [];
this.init();
}
WaterFall.prototype = {
init: function() {
var obj = this;
obj.colLen = [];
obj.wid = obj.child[0].offsetWidth;
obj.col = Math.floor(obj.parent.width() / (obj.wid + obj.spa));
for (var i = 0; i < obj.col; i++) {
obj.colLen.push(0);
};
for (var i = 0; i < obj.child.length; i++) {
obj.push(obj.child[i]);
};
// 添加加载更多
obj.loadmore();
return obj.child;
},
push: function(elem){
var index = 0;
var elem = $(elem);
var min = this.colLen[0];
for (var i = 1; i < this.col; i++) {
if(min > this.colLen[i]) {
min = this.colLen[i];
index = i;
}
};
var top = this.colLen[index] + this.spa;
var left = (this.spa + this.wid) * index + this.spa;
elem.css({
‘top‘: top,
‘left‘: left
});
this.colLen[index] += elem.height() + this.spa;
},
loadmore: function() {
var obj = this;
var max = -1;
var node = obj.parent.find(‘.app-loadmore‘);
for (var i = obj.child.length - 1; i >= obj.child.length - 1 - obj.col; i--) {
if(obj.child[i] && obj.child[i].height > max)
max = obj.child[i].height();
};
max += Math.max.apply(Math,this.colLen);
max = Math.max(max, obj.parent.parent().height());
node.css(‘top‘, max);
obj.parent.height(max);
}
};
return waterfall;
})();
原文:http://my.oschina.net/u/1402334/blog/514835