這樣的布局並不陌生,從2011年Pinterest創立以來,中國互聯網就迅速掀起了一股模仿Pinterest的熱潮,國內有眾多網站采用瀑布流的布局方式,例如花瓣網、美麗說等等。而事實上在中國互聯網,模仿一些在國外被人看好的模式(當然,你也可以說是山寨或抄襲,呵呵!!)向來都是一個不錯的idea。
OK,現在進入正題。這裡主要介紹瀑布流的一種實現方法:絕對定位(CSS)+Javascript+AJax+JSon。簡單一點如果不做滾動加載的話就是絕對定位(CSS)+Javascript了,AJax和JSon是滾動加載更多內容的時候用到的。
下面是實現思路:
1、計算頁面的寬度,計算出頁面可放數據塊的列數(如上圖所示就有6列)。
2、將各個數據塊的高度尺寸記入數組中(需要等所有圖片加載完成,否則無法知道圖片的高度)。
3、用絕對定位先將頁面第一行填滿,因為第一行的top位置都是一樣的,然後用數組記錄每一列的總高度。
4、繼續用絕對定位將其他數據塊定位在最短的一列的位置之後然後更新該列的高度。
5、當浏覽器窗口大小改變時,重新執行一次上面1-4步以重新排放(列數隨頁面寬度而改變,因而需要重新排放)。
6、滾動條滾動到底部時加載新的數據進來後也是定位在最短的一列的位置之後然後更新該列的高度。
思路有了,然後就是如何用代碼實現。當然,如果看完以上的6個步驟你已經知道如何實現,那麼下面的內容大可不必細看。
首先在頁面上寫好基本的Html和CSS(為方便起見,CSS就不外聯了),代碼如下:
1 DOCTYPE Html> 2 <Html> 3 <head> 4 <meta http-equiv="Content-Type"content="text/Html; charset=UTF-8"> 5 <title>瀑布流布局title> 6 <styletype="text/CSS"> 7 body{margin:0; font-family:微軟雅黑;} 8 #flow-box{margin:10px auto 0 auto; padding:0; position:relative} 9 #flow-box li{ 10 width:190px; position:absolute; padding:10px; border:solid 1px #efefef; list-style:none; 11 opacity:0; 12 -moz-opacity:0; 13filter:alpha(opacity=0); 14 -webkit-transition:opacity 500ms ease-in-out; 15 -moz-transition:opacity 500ms ease-in-out; 16 -o-transition:opaicty 500ms ease-in-out; 17 transition:opaicty 500ms ease-in-out;} 18 #flow-box li img{width:100%;} 19 #flow-box li a{display:block; width:100%; text-align:center; font-size:14px;color:#333; line-height:18px; margin-top:10px; text-decoration:none;}20 .loadwrap{position:absolute; left:0; width:100%; text-align:center;} 21 style> 22 head> 23 <body> 24 <ul id="flow-box"> 25<li><img src="http://www.mitxiong.com/NewsImages/2012121821504156.jpg"/><a href="#">圖片標題1a>li> 26 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012112718241731.jpg" /><ahref="#">圖片標題2a>li> 27 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012111806582944.jpg" /><ahref="#">圖片標題3a>li> 28 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012110907231232.jpg" /><ahref="#">圖片標題4a>li> 29 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012110406319529.jpg" /><ahref="#">圖片標題5a>li> 30 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012101808066955.jpg" /><ahref="#">圖片標題6a>li> 31 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012101307276582.jpg" /><ahref="#">圖片標題7a>li> 32 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012082223432719.jpg" /><ahref="#">圖片標題8a>li> 33 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012082121509065.jpg" /><ahref="#">圖片標題9a>li> 34 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012081922387254.jpg" /><ahref="#">圖片標題10a>li> 35 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012081700252403.jpg" /><ahref="#">圖片標題11a>li> 36 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012081407597304.jpg" /><ahref="#">圖片標題12a>li> 37 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012081218248259.jpg" /><ahref="#">圖片標題13a>li> 38 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012080621278799.jpg" /><ahref="#">圖片標題14a>li> 39 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012072907484455.jpg" /><ahref="#">圖片標題15a>li> 40 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012072521564314.jpg" /><ahref="#">圖片標題16a>li> 41 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012072507238259.jpg" /><ahref="#">圖片標題17a>li> 42 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012072409035684.jpg" /><ahref="#">圖片標題18a>li> 43 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012072219405236.jpg" /><ahref="#">圖片標題19a>li> 44 <li><imgsrc="http://www.mitxiong.com/NewsImages/2012071218416980.jpg" /><ahref="#">圖片標題20a>li> 45 ul> 46 <div id="loadimg" class="loadwrap"><img src="Images/load.jpg" />div> 47 body> 48 Html>
以上代碼非常簡單,可以看出頁面最初將會先加載20個數據塊。值得一提的是在CSS裡面定義了opacity為 0,目的是在數據塊未排放好之前先隱藏起來,排放好後再將opacity設為1顯示出來,另外這裡用了CSS3的transition做一點體驗上的升 級;還有一點就是可以看到頁面底部有一個id為“loading”的DIV,用來表示數據正在加載中。下面開始用JS實現以上思路(6個步驟)。
1、計算頁面的寬度,計算出頁面可放數據塊的列數
1 <script type="text/Javascript"> 2 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離 3 var w =document.documentElement.offsetWidth;//計算頁面寬度 4 var ul =document.getElementById("flow-box"); 5 var li =ul.getElementsByTagName("li"); 6 var iw = li[0].offsetWidth + mh;//計算數據塊的寬度 7 var c = Math.floor(w / iw);//計算列數 8 ul.style.width= iw * c - mh + "px";//設置ul的寬度至適合便可以利用CSS定義的margin把所有內容居中
9 } 10 script>
注釋寫得非常明白,這一步不說應該都很容易懂。
2、將各個數據塊的高度尺寸記入數組中
1 <script type="text/Javascript"> 2 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離 3 //... 省略上一步的部份代碼 ... 8 ul.style.width = iw * c - mh + "px";//設置ul的寬度至適合便可以利用CSS定義的margin把所有內容居中 9 10 var liLen = li.length; 11 varlenArr = []; 12 for (var i = 0; i < liLen; i++) {//遍歷每一個數據塊將高度記入數組 13 lenArr.push(li[i].offsetHeight); 14 } 15 } 16 script>
由於數據塊裡面含有圖片,也沒有給定圖片的尺寸,所以需要等待圖片加載完成後方可獲取其高度;那麼可以在window.onload的時候調用flow方法。代碼變成:
1 <script type="text/Javascript"> 2 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離 3 //... 省略上一步的部份代碼 ... 8 ul.style.width = iw * c - mh + "px";//設置ul的寬度至適合便可以利用CSS定義的margin把所有內容居中 9 10 var liLen = li.length; 11 varlenArr = []; 12 for (var i = 0; i < liLen; i++) {//遍歷每一個數據塊將高度記入數組 13 lenArr.push(li[i].offsetHeight); 14 } 15 } 16 //圖片加載完成後執行 17 window.onload = function() {flow(10, 10)};
18 script>
3、用絕對定位先將頁面第一行填滿,因為第一行的top位置都是一樣的,然後用數組記錄每一列的總高度。
1 <script type="text/Javascript"> 2 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離 //... 省略上一步的部份代碼 ...
12 for (var i = 0; i < liLen; i++) {//遍歷每一個數據塊將高度記入數組 13lenArr.push(li[i].offsetHeight); 14 } 15 16 var oArr = []; 17 for (vari = 0; i < c; i++) {//把第一行排放好,並將每一列的高度記入數據oArr 18li[i].style.top = "0"; 19 li[i].style.left = iw * i + "px"; 20li[i].style.opacity = "1"; 21 li[i].style["-moz-opacity"] = "1"; 22li[i].style["filter"] = "alpha(opacity=100)"; 23 oArr.push(lenArr[i]);24 } 25 document.getElementById("loadimg").style.top =_getMaxValue(oArr) + 50 + "px";//將loading移到下面 26 } 27 //圖片加載完成後執行 28 window.onload = function() {flow(10, 10)}; 29 //獲取數字數組的最大值 30 function _getMaxValue(arr) { 31 var a = arr[0]; 32 for(var k in arr) { 33 if (arr[k] > a) { 34 a = arr[k]; 35 } 36 } 37return a; 38 } 39 script>
截至目前為止,可以到浏覽器裡面預覽一下效果: