0x01 前言
今天在tumblr上看到其瀑布流布局,如下图,觉得很有意思便研究了下,发现tumblr使用position:absolute
布局的。
照我之前的想法呢,是根据窗口大小,建立N条Col,然后依次将item append到col中。这样成本会小很多,因为只需要写好col的css即可:float:left
或display:inline-block
。
0x02 代码编写
HTML,CSS
结构很简单,具体请参考底部的实例。
js
先上全部JS代码
$(function() {
var data = Mock.mock({
'items|80': [{
bgcolor: 'whitesmoke',
title: '@title(3,5)',
passage: '@paragraph(1,3)',
img: '@dataImage(300x220)'
}]
}).items;
var itemWidth = 320;
var itemTpl = $('#tpl .falls-item');
var wrapper = $('.list-container');
var promiseArr = [];
var colCount = Math.floor((window.innerWidth - 17) / 320);
var colTop = []; //每一列最后的高度值
for (var i = 0; i < colCount; i++) {
colTop.push(0);
}
console.log(colCount);
data.forEach(function(val, index) {
var item = itemTpl.clone();
var colIndex = (index % colCount); //计算出列索引
var itemLeft = colIndex * itemWidth; //列数index * 宽度 = left值
var itemTop = colTop[colIndex]; //当前列最后的高度值
item.find('.title').text(val.title);
item.find('.content').text(val.passage);
item.find('img').attr('data-src', val.img).attr('data-index', index);
item.css({
'background-color': val.bgcolor,
width: itemWidth,
});
wrapper.append(item);
var dtd = $.Deferred();
promiseArr.push(dtd);
var prev = new Date().getTime();
setTimeout(function() {
item.css({
left: itemLeft,
top: itemTop
});
console.log(new Date().getTime() - prev);
setTimeout(dtd.resolve, 850);
}, 300)
//插入后更新最后高度值
colTop[colIndex] += $(item).height();
});
var imgs = $('.list-container img[data-lazy-load]');
$.when.apply($, promiseArr).done(function() {
console.log('animate Done');
imgs.scrollFire(150, function(el) {
//console.log(el.dataset.index);
el.src = el.dataset.src;
$(el).addClass('animated fadeIn');
});
$(window).trigger('scroll');
})
我就捡重点讲~
首先我们用MockJS生成随机数据,格式如下:
var data = Mock.mock({
'items|80': [{
bgcolor: 'whitesmoke',
title: '@title(3,5)',
passage: '@paragraph(1,3)',
img: '@dataImage(300x220)'
}]
}).items;
生成好数据后,我们做一些初始化准备
var itemWidth = 320;//这里的列宽我们预设为320px,否则不好控制。
var colCount = Math.floor((window.innerWidth - 17) / 320); //计算列数,减去17是减去滚动条的宽度
var promiseArr = []; 为每个动画元素生成promise,在动画执行完毕时,可以通知我们。
接着就是对数组循环遍历,插入HTML。
var colIndex = (index % colCount); //计算出列索引,这里用取余的方式
var itemLeft = colIndex * itemWidth; //列数index * 宽度 = left值
var itemTop = colTop[colIndex]; //当前列最后的高度值,插入HTML后,此值将会更新。
0x03 注意要点
滚动条
当body内容超过window大小,则会出现滚动条,滚动条是占据空间的。
window.innerWidth
$(window).height() == $(body).width()
$.when
$.when的调用方法是$.when(arg1,arg2)
,如果直接传入数组,会执行不成功,因此我们用$.when.apply()
的方式。