javascript
JavaScript实现自适应宽度的瀑布流
摘要: 主要介紹瀑布流的一種實現方法:絕對定位(css)+javascript+ajax+json。簡單一點如果不做滾動加載的話就是絕對定位(css)+javascript了,ajax和json是滾動加載更多內容的時候用到的。
?
?? ? ? 這樣的布局并不陌生,從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 <style type="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; 13 filter: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><img src="http://www.mitxiong.com/NewsImages/2012112718241731.jpg" /><a href="#">圖片標題2a>li> 27 <li><img src="http://www.mitxiong.com/NewsImages/2012111806582944.jpg" /><a href="#">圖片標題3a>li> 28 <li><img src="http://www.mitxiong.com/NewsImages/2012110907231232.jpg" /><a href="#">圖片標題4a>li> 29 <li><img src="http://www.mitxiong.com/NewsImages/2012110406319529.jpg" /><a href="#">圖片標題5a>li> 30 <li><img src="http://www.mitxiong.com/NewsImages/2012101808066955.jpg" /><a href="#">圖片標題6a>li> 31 <li><img src="http://www.mitxiong.com/NewsImages/2012101307276582.jpg" /><a href="#">圖片標題7a>li> 32 <li><img src="http://www.mitxiong.com/NewsImages/2012082223432719.jpg" /><a href="#">圖片標題8a>li> 33 <li><img src="http://www.mitxiong.com/NewsImages/2012082121509065.jpg" /><a href="#">圖片標題9a>li> 34 <li><img src="http://www.mitxiong.com/NewsImages/2012081922387254.jpg" /><a href="#">圖片標題10a>li> 35 <li><img src="http://www.mitxiong.com/NewsImages/2012081700252403.jpg" /><a href="#">圖片標題11a>li> 36 <li><img src="http://www.mitxiong.com/NewsImages/2012081407597304.jpg" /><a href="#">圖片標題12a>li> 37 <li><img src="http://www.mitxiong.com/NewsImages/2012081218248259.jpg" /><a href="#">圖片標題13a>li> 38 <li><img src="http://www.mitxiong.com/NewsImages/2012080621278799.jpg" /><a href="#">圖片標題14a>li> 39 <li><img src="http://www.mitxiong.com/NewsImages/2012072907484455.jpg" /><a href="#">圖片標題15a>li> 40 <li><img src="http://www.mitxiong.com/NewsImages/2012072521564314.jpg" /><a href="#">圖片標題16a>li> 41 <li><img src="http://www.mitxiong.com/NewsImages/2012072507238259.jpg" /><a href="#">圖片標題17a>li> 42 <li><img src="http://www.mitxiong.com/NewsImages/2012072409035684.jpg" /><a href="#">圖片標題18a>li> 43 <li><img src="http://www.mitxiong.com/NewsImages/2012072219405236.jpg" /><a href="#">圖片標題19a>li> 44 <li><img src="http://www.mitxiong.com/NewsImages/2012071218416980.jpg" /><a href="#">圖片標題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 var lenArr = []; 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 var lenArr = []; 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++) {//遍歷每一個數據塊將高度記入數組 13 lenArr.push(li[i].offsetHeight); 14 } 15 16 var oArr = []; 17 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數據oArr 18 li[i].style.top = "0"; 19 li[i].style.left = iw * i + "px"; 20 li[i].style.opacity = "1"; 21 li[i].style["-moz-opacity"] = "1"; 22 li[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 } 37 return a; 38 } 39 script> ?
? 截至目前為止,可以到瀏覽器里面預覽一下效果:
?
?
?
OK,接下來開始放置其他的數據塊了,也就是到思路的第4步了。
?
4、繼續用絕對定位將其他數據塊定位在最短的一列的位置之后然后更新該列的高度。
?
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略上一步的部份代碼 ...17 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數據oArr 18 li[i].style.top = "0"; 19 li[i].style.left = iw * i + "px"; 20 li[i].style.opacity = "1"; 21 li[i].style["-moz-opacity"] = "1"; 22 li[i].style["filter"] = "alpha(opacity=100)"; 23 oArr.push(lenArr[i]); 24 } 25 26 for (var i = c; i < liLen; i++) {//將其他數據塊定位到最短的一列后面,然后再更新該列的高度 27 var x = _getMinKey(oArr);//獲取最短的一列的索引值 28 li[i].style.top = oArr[x] + mv + "px"; 29 li[i].style.left = iw * x + "px"; 30 li[i].style.opacity = "1"; 31 li[i].style["-moz-opacity"] = "1"; 32 li[i].style["filter"] = "alpha(opacity=100)"; 33 oArr[x] = lenArr[i] + oArr[x] + mv;//更新該列的高度 34 } 35 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//將loading移到下面 36 } 37 //圖片加載完成后執行 38 window.onload = function() {flow(10, 10)}; 39 //獲取數字數組的最大值 40 function _getMaxValue(arr) { 41 //... 省略部份代碼 ...
48 } 49 //獲取數字數組最小值的索引 50 function _getMinKey(arr) { 51 var a = arr[0]; 52 var b = 0; 53 for (var k in arr) { 54 if (arr[k] < a) { 55 a = arr[k]; 56 b = k; 57 } 58 } 59 return b; 60 } 61 script> ?
?
到這一步可以到瀏覽器里面再看一次效果,可以說整個瀑布流的雛形都出來了:
?
?
?
?
?
?
?
?
?
?
5、當瀏覽器窗口大小改變時,重新執行一次上面1-4步以重新排放
?
?
?
這一步操作起來也相當便捷,在改變窗口大小時,再執行一次flow方法即可
?
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略部份代碼 ...37 //圖片加載完成后執行 38 window.onload = function() {flow(10, 10)}; 39 //改變窗口大小時重新布局 40 var re; 41 window.onresize = function() { 42 clearTimeout(re); 43 re = setTimeout(function() {flow(10, 10);}, 200); 44 } 45 //獲取數字數組的最大值 46 function _getMaxValue(arr) { 47 //... 省略部份代碼 ...
54 } 55 //獲取數字數組最小值的索引 56 function _getMinKey(arr) { 57 //... 省略部分代碼 ...
66 } 67 script> ?
?
這里值得注意的便是setTimeout,由于onresize的觸發頻率非常高,用setTimout設定一個間隔時間可以減低flow方法的執行頻率,降低性能損耗。
?
?
?
6、滾動條滾動到底部時加載新的數據進來后也是定位在最短的一列的位置之后然后更新該列的高度。
?
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略部份代碼 ...35 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//將loading移到下面36 37 function scroll() {//滾動加載數據38 var st = oArr[_getMinKey(oArr)];39 var scrollTop = document.documentElement.scrollTop > document.body.scrollTop? document.documentElement.scrollTop : document.body.scrollTop;40 if (scrollTop >= st - document.documentElement.clientHeight) {41 window.onscroll = null;//為防止重復執行,先清除事件42 _request(null, "GetList.php", function(data) {//當滾動到達最短的一列的距離時便發送ajax請求新的數據,然后執行回調函數43 _addItem(data.d, function() {//追加數據44 var liLenNew = li.length;45 for(var i = liLen; i < liLenNew; i++) {46 lenArr.push(li[i].offsetHeight);47 }48 for(var i = liLen; i < liLenNew; i++) {49 var x = _getMinKey(oArr);50 li[i].style.top = oArr[x] + 10 + "px";51 li[i].style.left = iw * x + "px";52 li[i].style.opacity = "1";53 li[i].style["-moz-opacity"] = "1";54 li[i].style["filter"] = "alpha(opacity=100)";55 oArr[x] = lenArr[i] + oArr[x] + 10;56 }57 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//loading向下移位58 liLen = liLenNew;59 window.onscroll = scroll;//執行完成,恢愎onscroll事件60 });61 })62 }63 }64 window.onscroll =scroll;65 }66 //圖片加載完成后執行67 window.onload = function() {flow(10, 10)};68 //... 省略部份代碼 ...
74 //追加項75 function _addItem(arr, callback) {76 var _html = "";77 var a = 0;78 var l = arr.length;79 (function loadimg() {80 var img = new Image();81 img.onload = function() {82 a += 1;83 if (a == l) {84 for (var k in arr) {85 var img = new Image();86 img.src = arr[k].img;87 _html += '
- ' + arr[k].img + '" />' + arr[k].title + '
147 } 148 //獲取數字數組最小值的索引 149 function _getMinKey(arr) { 150 //... 省略部份代碼 ...
159 } 160 script> ?
?
這一步涉及的代碼比較多,簡單概括其實就是多了幾個方法:scroll()、_addItem()、_request()、_appendhtml()。
?
?? ? ?主要是看scroll()。在這里_addItem()和_requeat()是供scroll()調用的,而_appendhtml()是供_addItem()調用的。
?
?
?
這一步的整個過程是:當頁面滾動到最短的一列數據的底部時就發出ajax請求加載新的數據,然后待數據中的圖片全部load完后就追加到頁面上,然后將這些數據項的高度寫入到數組lenArr中,并對新加入的這些數據項進行定位,按照每一項都放在最短列的后面的規則而排放在適當的位置上,最后再將loading圖片向下移到最底部的位置。
?
?
?
總結以上的整個思路,有4個地方值得一說:
?
?
?
1、縮放瀏覽器窗口時,onresize的觸發很頻繁,為降低性能損耗,需要待縮放結束后再執行重排,以上思路是使用setTimeout來處理。
?
?
?
2、頁面滾動到最下面加載新數據的時候,只需對新數據排列。
?
?
?
3、以上思路中加載新數據要等圖片都加載完成后才知道其高度,但實際項目中最好是服務器能給定高度值。
?
?
?
4、滾動觸發加載新數據時,要避免事件多次觸發,以上思路是將onscroll事件置為空,加載完成后再將事件恢復。
?
?
?
最后附上完整的代碼:
?
?
?
flow.html
?
<!DOCTYPE html>2 <html>3 <head>4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">5 <title>瀑布流布局</title>6 <style type="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;13 filter: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="#">圖片標題1</a></li>26 <li><img src="http://www.mitxiong.com/NewsImages/2012112718241731.jpg" /><a href="#">圖片標題2</a></li>27 <li><img src="http://www.mitxiong.com/NewsImages/2012111806582944.jpg" /><a href="#">圖片標題3</a></li>28 <li><img src="http://www.mitxiong.com/NewsImages/2012110907231232.jpg" /><a href="#">圖片標題4</a></li>29 <li><img src="http://www.mitxiong.com/NewsImages/2012110406319529.jpg" /><a href="#">圖片標題5</a></li>30 <li><img src="http://www.mitxiong.com/NewsImages/2012101808066955.jpg" /><a href="#">圖片標題6</a></li>31 <li><img src="http://www.mitxiong.com/NewsImages/2012101307276582.jpg" /><a href="#">圖片標題7</a></li>32 <li><img src="http://www.mitxiong.com/NewsImages/2012082223432719.jpg" /><a href="#">圖片標題8</a></li>33 <li><img src="http://www.mitxiong.com/NewsImages/2012082121509065.jpg" /><a href="#">圖片標題9</a></li>34 <li><img src="http://www.mitxiong.com/NewsImages/2012081922387254.jpg" /><a href="#">圖片標題10</a></li>35 <li><img src="http://www.mitxiong.com/NewsImages/2012081700252403.jpg" /><a href="#">圖片標題11</a></li>36 <li><img src="http://www.mitxiong.com/NewsImages/2012081407597304.jpg" /><a href="#">圖片標題12</a></li>37 <li><img src="http://www.mitxiong.com/NewsImages/2012081218248259.jpg" /><a href="#">圖片標題13</a></li>38 <li><img src="http://www.mitxiong.com/NewsImages/2012080621278799.jpg" /><a href="#">圖片標題14</a></li>39 <li><img src="http://www.mitxiong.com/NewsImages/2012072907484455.jpg" /><a href="#">圖片標題15</a></li>40 <li><img src="http://www.mitxiong.com/NewsImages/2012072521564314.jpg" /><a href="#">圖片標題16</a></li>41 <li><img src="http://www.mitxiong.com/NewsImages/2012072507238259.jpg" /><a href="#">圖片標題17</a></li>42 <li><img src="http://www.mitxiong.com/NewsImages/2012072409035684.jpg" /><a href="#">圖片標題18</a></li>43 <li><img src="http://www.mitxiong.com/NewsImages/2012072219405236.jpg" /><a href="#">圖片標題19</a></li>44 <li><img src="http://www.mitxiong.com/NewsImages/2012071218416980.jpg" /><a href="#">圖片標題20</a></li>45 </ul>46 <div id="loadimg" class="loadwrap"><img src="Images/load.jpg" /></div>47 <script type="text/javascript">48 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離49 var w = document.documentElement.offsetWidth;//計算頁面寬度50 var ul = document.getElementById("flow-box");51 var li = ul.getElementsByTagName("li");52 var iw = li[0].offsetWidth + mh;//計算數據塊的寬度53 var c = Math.floor(w / iw);//計算列數54 ul.style.width = iw * c - mh + "px";//設置ul的寬度至適合便可以利用css定義的margin把所有內容居中55 56 var liLen = li.length;57 var lenArr = [];58 for (var i = 0; i < liLen; i++) {//遍歷每一個數據塊將高度記入數組59 lenArr.push(li[i].offsetHeight);60 }61 62 var oArr = [];63 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數據oArr64 li[i].style.top = "0";65 li[i].style.left = iw * i + "px";66 li[i].style.opacity = "1";67 li[i].style["-moz-opacity"] = "1";68 li[i].style["filter"] = "alpha(opacity=100)";69 oArr.push(lenArr[i]);70 }71 72 for (var i = c; i < liLen; i++) {//將其他數據塊定位到最短的一列后面,然后再更新該列的高度73 var x = _getMinKey(oArr);//獲取最短的一列的索引值74 li[i].style.top = oArr[x] + mv + "px";75 li[i].style.left = iw * x + "px";76 li[i].style.opacity = "1";77 li[i].style["-moz-opacity"] = "1";78 li[i].style["filter"] = "alpha(opacity=100)";79 oArr[x] = lenArr[i] + oArr[x] + mv;//更新該列的高度80 }81 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//將loading移到下面82 83 function scroll() {//滾動加載數據84 var st = oArr[_getMinKey(oArr)];85 var scrollTop = document.documentElement.scrollTop > document.body.scrollTop? document.documentElement.scrollTop : document.body.scrollTop;86 if (scrollTop >= st - document.documentElement.clientHeight) {87 window.onscroll = null;//為防止重復執行,先清除事件88 _request(null, "GetList.php", function(data) {//當滾動到達最短的一列的距離時便發送ajax請求新的數據,然后執行回調函數89 _addItem(data.d, function() {//追加數據90 var liLenNew = li.length;91 for(var i = liLen; i < liLenNew; i++) {92 lenArr.push(li[i].offsetHeight);93 }94 for(var i = liLen; i < liLenNew; i++) {95 var x = _getMinKey(oArr);96 li[i].style.top = oArr[x] + 10 + "px";97 li[i].style.left = iw * x + "px";98 li[i].style.opacity = "1";99 li[i].style["-moz-opacity"] = "1"; 100 li[i].style["filter"] = "alpha(opacity=100)"; 101 oArr[x] = lenArr[i] + oArr[x] + 10; 102 } 103 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//loading向下移位 104 liLen = liLenNew; 105 window.onscroll = scroll;//執行完成,恢愎onscroll事件 106 }); 107 }) 108 } 109 } 110 window.onscroll =scroll; 111 } 112 //圖片加載完成后執行 113 window.onload = function() {flow(10, 10)}; 114 //改變窗口大小時重新布局 115 var re; 116 window.onresize = function() { 117 clearTimeout(re); 118 re = setTimeout(function() {flow(10, 10);}, 200); 119 } 120 //追加項 121 function _addItem(arr, callback) { 122 var _html = ""; 123 var a = 0; 124 var l = arr.length; 125 (function loadimg() { 126 var轉自:html5中國(http://www.html5cn.org/article-4652-3.html) 1 <!DOCTYPE html>2 <html>3 <head>4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">5 <title>瀑布流布局</title>6 <style type="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;13 filter: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="#">圖片標題1</a></li>26 <li><img src="http://www.mitxiong.com/NewsImages/2012112718241731.jpg" /><a href="#">圖片標題2</a></li>27 <li><img src="http://www.mitxiong.com/NewsImages/2012111806582944.jpg" /><a href="#">圖片標題3</a></li>28 <li><img src="http://www.mitxiong.com/NewsImages/2012110907231232.jpg" /><a href="#">圖片標題4</a></li>29 <li><img src="http://www.mitxiong.com/NewsImages/2012110406319529.jpg" /><a href="#">圖片標題5</a></li>30 <li><img src="http://www.mitxiong.com/NewsImages/2012101808066955.jpg" /><a href="#">圖片標題6</a></li>31 <li><img src="http://www.mitxiong.com/NewsImages/2012101307276582.jpg" /><a href="#">圖片標題7</a></li>32 <li><img src="http://www.mitxiong.com/NewsImages/2012082223432719.jpg" /><a href="#">圖片標題8</a></li>33 <li><img src="http://www.mitxiong.com/NewsImages/2012082121509065.jpg" /><a href="#">圖片標題9</a></li>34 <li><img src="http://www.mitxiong.com/NewsImages/2012081922387254.jpg" /><a href="#">圖片標題10</a></li>35 <li><img src="http://www.mitxiong.com/NewsImages/2012081700252403.jpg" /><a href="#">圖片標題11</a></li>36 <li><img src="http://www.mitxiong.com/NewsImages/2012081407597304.jpg" /><a href="#">圖片標題12</a></li>37 <li><img src="http://www.mitxiong.com/NewsImages/2012081218248259.jpg" /><a href="#">圖片標題13</a></li>38 <li><img src="http://www.mitxiong.com/NewsImages/2012080621278799.jpg" /><a href="#">圖片標題14</a></li>39 <li><img src="http://www.mitxiong.com/NewsImages/2012072907484455.jpg" /><a href="#">圖片標題15</a></li>40 <li><img src="http://www.mitxiong.com/NewsImages/2012072521564314.jpg" /><a href="#">圖片標題16</a></li>41 <li><img src="http://www.mitxiong.com/NewsImages/2012072507238259.jpg" /><a href="#">圖片標題17</a></li>42 <li><img src="http://www.mitxiong.com/NewsImages/2012072409035684.jpg" /><a href="#">圖片標題18</a></li>43 <li><img src="http://www.mitxiong.com/NewsImages/2012072219405236.jpg" /><a href="#">圖片標題19</a></li>44 <li><img src="http://www.mitxiong.com/NewsImages/2012071218416980.jpg" /><a href="#">圖片標題20</a></li>45 </ul>46 <div id="loadimg" class="loadwrap"><img src="Images/load.jpg" /></div>47 <script type="text/javascript">48 function flow(mh, mv) {//參數mh和mv是定義數據塊之間的間距,mh是水平距離,mv是垂直距離49 var w = document.documentElement.offsetWidth;//計算頁面寬度50 var ul = document.getElementById("flow-box");51 var li = ul.getElementsByTagName("li");52 var iw = li[0].offsetWidth + mh;//計算數據塊的寬度53 var c = Math.floor(w / iw);//計算列數54 ul.style.width = iw * c - mh + "px";//設置ul的寬度至適合便可以利用css定義的margin把所有內容居中55 56 var liLen = li.length;57 var lenArr = [];58 for (var i = 0; i < liLen; i++) {//遍歷每一個數據塊將高度記入數組59 lenArr.push(li[i].offsetHeight);60 }61 62 var oArr = [];63 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數據oArr64 li[i].style.top = "0";65 li[i].style.left = iw * i + "px";66 li[i].style.opacity = "1";67 li[i].style["-moz-opacity"] = "1";68 li[i].style["filter"] = "alpha(opacity=100)";69 oArr.push(lenArr[i]);70 }71 72 for (var i = c; i < liLen; i++) {//將其他數據塊定位到最短的一列后面,然后再更新該列的高度73 var x = _getMinKey(oArr);//獲取最短的一列的索引值74 li[i].style.top = oArr[x] + mv + "px";75 li[i].style.left = iw * x + "px";76 li[i].style.opacity = "1";77 li[i].style["-moz-opacity"] = "1";78 li[i].style["filter"] = "alpha(opacity=100)";79 oArr[x] = lenArr[i] + oArr[x] + mv;//更新該列的高度80 }81 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//將loading移到下面82 83 function scroll() {//滾動加載數據84 var st = oArr[_getMinKey(oArr)];85 var scrollTop = document.documentElement.scrollTop > document.body.scrollTop? document.documentElement.scrollTop : document.body.scrollTop;86 if (scrollTop >= st - document.documentElement.clientHeight) {87 window.onscroll = null;//為防止重復執行,先清除事件88 _request(null, "GetList.php", function(data) {//當滾動到達最短的一列的距離時便發送ajax請求新的數據,然后執行回調函數89 _addItem(data.d, function() {//追加數據90 var liLenNew = li.length;91 for(var i = liLen; i < liLenNew; i++) {92 lenArr.push(li[i].offsetHeight);93 }94 for(var i = liLen; i < liLenNew; i++) {95 var x = _getMinKey(oArr);96 li[i].style.top = oArr[x] + 10 + "px";97 li[i].style.left = iw * x + "px";98 li[i].style.opacity = "1";99 li[i].style["-moz-opacity"] = "1"; 100 li[i].style["filter"] = "alpha(opacity=100)"; 101 oArr[x] = lenArr[i] + oArr[x] + 10; 102 } 103 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//loading向下移位 104 liLen = liLenNew; 105 window.onscroll = scroll;//執行完成,恢愎onscroll事件 106 }); 107 }) 108 } 109 } 110 window.onscroll =scroll; 111 } 112 //圖片加載完成后執行 113 window.onload = function() {flow(10, 10)}; 114 //改變窗口大小時重新布局 115 var re; 116 window.onresize = function() { 117 clearTimeout(re); 118 re = setTimeout(function() {flow(10, 10);}, 200); 119 } 120 //追加項 121 function _addItem(arr, callback) { 122 var _html = ""; 123 var a = 0; 124 var l = arr.length; 125 (function loadimg() { 126
?
?
轉載于:https://www.cnblogs.com/h-change/archive/2013/03/29/2989517.html
總結
以上是生活随笔為你收集整理的JavaScript实现自适应宽度的瀑布流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多核运算
- 下一篇: JS 三级联动 下拉列表