用position: absolute佈局,而後計算top,leftcss
首先,將容器分紅幾列,記錄高度node
往最矮的列添加一個item服務器
以上的都是很簡單的實現思想,而今天的重點是item涉及圖片的時候,或者有懶加載狀況下的瀑布流。app
由於在這樣的狀況下,item的高度多是不定的,由於加載圖片的高度是不定的,因而怎麼樣獲取item的高度就是一個難題佈局
最簡單的方法就是後臺傳輸數據this
我參考了一下,花瓣網 http://huaban.com/ 它的作法是這樣的spa
服務器訪問頁面的時候,把幾個文件拼接輸出(根據個人觀察有(1)公用頁面(2)系統配置(3)引入的js(4)頁面數據(5)頁面收尾)prototype
在(4)頁面數據中,他就有了圖片的寬高,跟一系列能夠拼接成一個item的數據。在加載的時候,根據這些初始數據加載輸出,其中圖片的大小符合某種比例的話就有最大高度的限制,否則圖片就按照圖片高度輸出code
如下的是我沒有控制圖片高度的一個瀑布流實現代碼圖片
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; })();