javascript
JavaScript实现自适应宽度的瀑布流
摘要: 主要介紹瀑布流的一種實(shí)現(xiàn)方法:絕對(duì)定位(css)+javascript+ajax+json。簡(jiǎn)單一點(diǎn)如果不做滾動(dòng)加載的話就是絕對(duì)定位(css)+javascript了,ajax和json是滾動(dòng)加載更多內(nèi)容的時(shí)候用到的。
?
?? ? ? 這樣的布局并不陌生,從2011年P(guān)interest創(chuàng)立以來(lái),中國(guó)互聯(lián)網(wǎng)就迅速掀起了一股模仿Pinterest的熱潮,國(guó)內(nèi)有眾多網(wǎng)站采用瀑布流的布局方式,例如花瓣網(wǎng)、美麗說(shuō)等等。而事實(shí)上在中國(guó)互聯(lián)網(wǎng),模仿一些在國(guó)外被人看好的模式(當(dāng)然,你也可以說(shuō)是山寨或抄襲,呵呵!!)向來(lái)都是一個(gè)不錯(cuò)的idea。
?
OK,現(xiàn)在進(jìn)入正題。這里主要介紹瀑布流的一種實(shí)現(xiàn)方法:絕對(duì)定位(css)+javascript+ajax+json。簡(jiǎn)單一點(diǎn)如果不做滾動(dòng)加載的話就是絕對(duì)定位(css)+javascript了,ajax和json是滾動(dòng)加載更多內(nèi)容的時(shí)候用到的。
?
下面是實(shí)現(xiàn)思路:
?
1、計(jì)算頁(yè)面的寬度,計(jì)算出頁(yè)面可放數(shù)據(jù)塊的列數(shù)(如上圖所示就有6列)。
2、將各個(gè)數(shù)據(jù)塊的高度尺寸記入數(shù)組中(需要等所有圖片加載完成,否則無(wú)法知道圖片的高度)。
3、用絕對(duì)定位先將頁(yè)面第一行填滿,因?yàn)榈谝恍械膖op位置都是一樣的,然后用數(shù)組記錄每一列的總高度。
4、繼續(xù)用絕對(duì)定位將其他數(shù)據(jù)塊定位在最短的一列的位置之后然后更新該列的高度。
5、當(dāng)瀏覽器窗口大小改變時(shí),重新執(zhí)行一次上面1-4步以重新排放(列數(shù)隨頁(yè)面寬度而改變,因而需要重新排放)。
6、滾動(dòng)條滾動(dòng)到底部時(shí)加載新的數(shù)據(jù)進(jìn)來(lái)后也是定位在最短的一列的位置之后然后更新該列的高度。
?
思路有了,然后就是如何用代碼實(shí)現(xiàn)。當(dāng)然,如果看完以上的6個(gè)步驟你已經(jīng)知道如何實(shí)現(xiàn),那么下面的內(nèi)容大可不必細(xì)看。
?
首先在頁(yè)面上寫(xiě)好基本的HTML和CSS(為方便起見(jiàn),CSS就不外聯(lián)了),代碼如下:
? 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="#">圖片標(biāo)題1a>li> 26 <li><img src="http://www.mitxiong.com/NewsImages/2012112718241731.jpg" /><a href="#">圖片標(biāo)題2a>li> 27 <li><img src="http://www.mitxiong.com/NewsImages/2012111806582944.jpg" /><a href="#">圖片標(biāo)題3a>li> 28 <li><img src="http://www.mitxiong.com/NewsImages/2012110907231232.jpg" /><a href="#">圖片標(biāo)題4a>li> 29 <li><img src="http://www.mitxiong.com/NewsImages/2012110406319529.jpg" /><a href="#">圖片標(biāo)題5a>li> 30 <li><img src="http://www.mitxiong.com/NewsImages/2012101808066955.jpg" /><a href="#">圖片標(biāo)題6a>li> 31 <li><img src="http://www.mitxiong.com/NewsImages/2012101307276582.jpg" /><a href="#">圖片標(biāo)題7a>li> 32 <li><img src="http://www.mitxiong.com/NewsImages/2012082223432719.jpg" /><a href="#">圖片標(biāo)題8a>li> 33 <li><img src="http://www.mitxiong.com/NewsImages/2012082121509065.jpg" /><a href="#">圖片標(biāo)題9a>li> 34 <li><img src="http://www.mitxiong.com/NewsImages/2012081922387254.jpg" /><a href="#">圖片標(biāo)題10a>li> 35 <li><img src="http://www.mitxiong.com/NewsImages/2012081700252403.jpg" /><a href="#">圖片標(biāo)題11a>li> 36 <li><img src="http://www.mitxiong.com/NewsImages/2012081407597304.jpg" /><a href="#">圖片標(biāo)題12a>li> 37 <li><img src="http://www.mitxiong.com/NewsImages/2012081218248259.jpg" /><a href="#">圖片標(biāo)題13a>li> 38 <li><img src="http://www.mitxiong.com/NewsImages/2012080621278799.jpg" /><a href="#">圖片標(biāo)題14a>li> 39 <li><img src="http://www.mitxiong.com/NewsImages/2012072907484455.jpg" /><a href="#">圖片標(biāo)題15a>li> 40 <li><img src="http://www.mitxiong.com/NewsImages/2012072521564314.jpg" /><a href="#">圖片標(biāo)題16a>li> 41 <li><img src="http://www.mitxiong.com/NewsImages/2012072507238259.jpg" /><a href="#">圖片標(biāo)題17a>li> 42 <li><img src="http://www.mitxiong.com/NewsImages/2012072409035684.jpg" /><a href="#">圖片標(biāo)題18a>li> 43 <li><img src="http://www.mitxiong.com/NewsImages/2012072219405236.jpg" /><a href="#">圖片標(biāo)題19a>li> 44 <li><img src="http://www.mitxiong.com/NewsImages/2012071218416980.jpg" /><a href="#">圖片標(biāo)題20a>li> 45 ul> 46 <div id="loadimg" class="loadwrap"><img src="Images/load.jpg" />div> 47 body> 48 html> ?以上代碼非常簡(jiǎn)單,可以看出頁(yè)面最初將會(huì)先加載20個(gè)數(shù)據(jù)塊。值得一提的是在CSS里面定義了opacity為0,目的是在數(shù)據(jù)塊未排放好之前先隱藏起來(lái),排放好后再將opacity設(shè)為1顯示出來(lái),另外這里用了css3的transition做一點(diǎn)體驗(yàn)上的升級(jí);還有一點(diǎn)就是可以看到頁(yè)面底部有一個(gè)id為“l(fā)oading”的DIV,用來(lái)表示數(shù)據(jù)正在加載中。下面開(kāi)始用JS實(shí)現(xiàn)以上思路(6個(gè)步驟)。
?
1、計(jì)算頁(yè)面的寬度,計(jì)算出頁(yè)面可放數(shù)據(jù)塊的列數(shù)
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離3 var w = document.documentElement.offsetWidth;//計(jì)算頁(yè)面寬度4 var ul = document.getElementById("flow-box");5 var li = ul.getElementsByTagName("li");6 var iw = li[0].offsetWidth + mh;//計(jì)算數(shù)據(jù)塊的寬度7 var c = Math.floor(w / iw);//計(jì)算列數(shù)8 ul.style.width = iw * c - mh + "px";//設(shè)置ul的寬度至適合便可以利用css定義的margin把所有內(nèi)容居中9 } 10 script> ?
注釋寫(xiě)得非常明白,這一步不說(shuō)應(yīng)該都很容易懂。
?
2、將各個(gè)數(shù)據(jù)塊的高度尺寸記入數(shù)組中
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略上一步的部份代碼 ...8 ul.style.width = iw * c - mh + "px";//設(shè)置ul的寬度至適合便可以利用css定義的margin把所有內(nèi)容居中9 10 var liLen = li.length; 11 var lenArr = []; 12 for (var i = 0; i < liLen; i++) {//遍歷每一個(gè)數(shù)據(jù)塊將高度記入數(shù)組 13 lenArr.push(li[i].offsetHeight); 14 } 15 } 16 script> ?由于數(shù)據(jù)塊里面含有圖片,也沒(méi)有給定圖片的尺寸,所以需要等待圖片加載完成后方可獲取其高度;那么可以在window.onload的時(shí)候調(diào)用flow方法。代碼變成:
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略上一步的部份代碼 ...8 ul.style.width = iw * c - mh + "px";//設(shè)置ul的寬度至適合便可以利用css定義的margin把所有內(nèi)容居中9 10 var liLen = li.length; 11 var lenArr = []; 12 for (var i = 0; i < liLen; i++) {//遍歷每一個(gè)數(shù)據(jù)塊將高度記入數(shù)組 13 lenArr.push(li[i].offsetHeight); 14 } 15 } 16 //圖片加載完成后執(zhí)行 17 window.onload = function() {flow(10, 10)};18 script> ?
3、用絕對(duì)定位先將頁(yè)面第一行填滿,因?yàn)榈谝恍械膖op位置都是一樣的,然后用數(shù)組記錄每一列的總高度。
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離//... 省略上一步的部份代碼 ...12 for (var i = 0; i < liLen; i++) {//遍歷每一個(gè)數(shù)據(jù)塊將高度記入數(shù)組 13 lenArr.push(li[i].offsetHeight); 14 } 15 16 var oArr = []; 17 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數(shù)據(jù)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 //圖片加載完成后執(zhí)行 28 window.onload = function() {flow(10, 10)}; 29 //獲取數(shù)字?jǐn)?shù)組的最大值 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> ?
? 截至目前為止,可以到瀏覽器里面預(yù)覽一下效果:
?
?
?
OK,接下來(lái)開(kāi)始放置其他的數(shù)據(jù)塊了,也就是到思路的第4步了。
?
4、繼續(xù)用絕對(duì)定位將其他數(shù)據(jù)塊定位在最短的一列的位置之后然后更新該列的高度。
?
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略上一步的部份代碼 ...17 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數(shù)據(jù)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++) {//將其他數(shù)據(jù)塊定位到最短的一列后面,然后再更新該列的高度 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 //圖片加載完成后執(zhí)行 38 window.onload = function() {flow(10, 10)}; 39 //獲取數(shù)字?jǐn)?shù)組的最大值 40 function _getMaxValue(arr) { 41 //... 省略部份代碼 ...
48 } 49 //獲取數(shù)字?jǐn)?shù)組最小值的索引 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> ?
?
到這一步可以到瀏覽器里面再看一次效果,可以說(shuō)整個(gè)瀑布流的雛形都出來(lái)了:
?
?
?
?
?
?
?
?
?
?
5、當(dāng)瀏覽器窗口大小改變時(shí),重新執(zhí)行一次上面1-4步以重新排放
?
?
?
這一步操作起來(lái)也相當(dāng)便捷,在改變窗口大小時(shí),再執(zhí)行一次flow方法即可
?
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略部份代碼 ...37 //圖片加載完成后執(zhí)行 38 window.onload = function() {flow(10, 10)}; 39 //改變窗口大小時(shí)重新布局 40 var re; 41 window.onresize = function() { 42 clearTimeout(re); 43 re = setTimeout(function() {flow(10, 10);}, 200); 44 } 45 //獲取數(shù)字?jǐn)?shù)組的最大值 46 function _getMaxValue(arr) { 47 //... 省略部份代碼 ...
54 } 55 //獲取數(shù)字?jǐn)?shù)組最小值的索引 56 function _getMinKey(arr) { 57 //... 省略部分代碼 ...
66 } 67 script> ?
?
這里值得注意的便是setTimeout,由于onresize的觸發(fā)頻率非常高,用setTimout設(shè)定一個(gè)間隔時(shí)間可以減低flow方法的執(zhí)行頻率,降低性能損耗。
?
?
?
6、滾動(dòng)條滾動(dòng)到底部時(shí)加載新的數(shù)據(jù)進(jìn)來(lái)后也是定位在最短的一列的位置之后然后更新該列的高度。
?
? 1 <script type="text/javascript">2 function flow(mh, mv) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離3 //... 省略部份代碼 ...35 document.getElementById("loadimg").style.top = _getMaxValue(oArr) + 50 + "px";//將loading移到下面36 37 function scroll() {//滾動(dòng)加載數(shù)據(jù)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;//為防止重復(fù)執(zhí)行,先清除事件42 _request(null, "GetList.php", function(data) {//當(dāng)滾動(dòng)到達(dá)最短的一列的距離時(shí)便發(fā)送ajax請(qǐng)求新的數(shù)據(jù),然后執(zhí)行回調(diào)函數(shù)43 _addItem(data.d, function() {//追加數(shù)據(jù)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;//執(zhí)行完成,恢愎onscroll事件60 });61 })62 }63 }64 window.onscroll =scroll;65 }66 //圖片加載完成后執(zhí)行67 window.onload = function() {flow(10, 10)};68 //... 省略部份代碼 ...
74 //追加項(xiàng)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 //獲取數(shù)字?jǐn)?shù)組最小值的索引 149 function _getMinKey(arr) { 150 //... 省略部份代碼 ...
159 } 160 script> ?
?
這一步涉及的代碼比較多,簡(jiǎn)單概括其實(shí)就是多了幾個(gè)方法:scroll()、_addItem()、_request()、_appendhtml()。
?
?? ? ?主要是看scroll()。在這里_addItem()和_requeat()是供scroll()調(diào)用的,而_appendhtml()是供_addItem()調(diào)用的。
?
?
?
這一步的整個(gè)過(guò)程是:當(dāng)頁(yè)面滾動(dòng)到最短的一列數(shù)據(jù)的底部時(shí)就發(fā)出ajax請(qǐng)求加載新的數(shù)據(jù),然后待數(shù)據(jù)中的圖片全部load完后就追加到頁(yè)面上,然后將這些數(shù)據(jù)項(xiàng)的高度寫(xiě)入到數(shù)組lenArr中,并對(duì)新加入的這些數(shù)據(jù)項(xiàng)進(jìn)行定位,按照每一項(xiàng)都放在最短列的后面的規(guī)則而排放在適當(dāng)?shù)奈恢蒙?#xff0c;最后再將loading圖片向下移到最底部的位置。
?
?
?
總結(jié)以上的整個(gè)思路,有4個(gè)地方值得一說(shuō):
?
?
?
1、縮放瀏覽器窗口時(shí),onresize的觸發(fā)很頻繁,為降低性能損耗,需要待縮放結(jié)束后再執(zhí)行重排,以上思路是使用setTimeout來(lái)處理。
?
?
?
2、頁(yè)面滾動(dòng)到最下面加載新數(shù)據(jù)的時(shí)候,只需對(duì)新數(shù)據(jù)排列。
?
?
?
3、以上思路中加載新數(shù)據(jù)要等圖片都加載完成后才知道其高度,但實(shí)際項(xiàng)目中最好是服務(wù)器能給定高度值。
?
?
?
4、滾動(dòng)觸發(fā)加載新數(shù)據(jù)時(shí),要避免事件多次觸發(fā),以上思路是將onscroll事件置為空,加載完成后再將事件恢復(fù)。
?
?
?
最后附上完整的代碼:
?
?
?
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="#">圖片標(biāo)題1</a></li>26 <li><img src="http://www.mitxiong.com/NewsImages/2012112718241731.jpg" /><a href="#">圖片標(biāo)題2</a></li>27 <li><img src="http://www.mitxiong.com/NewsImages/2012111806582944.jpg" /><a href="#">圖片標(biāo)題3</a></li>28 <li><img src="http://www.mitxiong.com/NewsImages/2012110907231232.jpg" /><a href="#">圖片標(biāo)題4</a></li>29 <li><img src="http://www.mitxiong.com/NewsImages/2012110406319529.jpg" /><a href="#">圖片標(biāo)題5</a></li>30 <li><img src="http://www.mitxiong.com/NewsImages/2012101808066955.jpg" /><a href="#">圖片標(biāo)題6</a></li>31 <li><img src="http://www.mitxiong.com/NewsImages/2012101307276582.jpg" /><a href="#">圖片標(biāo)題7</a></li>32 <li><img src="http://www.mitxiong.com/NewsImages/2012082223432719.jpg" /><a href="#">圖片標(biāo)題8</a></li>33 <li><img src="http://www.mitxiong.com/NewsImages/2012082121509065.jpg" /><a href="#">圖片標(biāo)題9</a></li>34 <li><img src="http://www.mitxiong.com/NewsImages/2012081922387254.jpg" /><a href="#">圖片標(biāo)題10</a></li>35 <li><img src="http://www.mitxiong.com/NewsImages/2012081700252403.jpg" /><a href="#">圖片標(biāo)題11</a></li>36 <li><img src="http://www.mitxiong.com/NewsImages/2012081407597304.jpg" /><a href="#">圖片標(biāo)題12</a></li>37 <li><img src="http://www.mitxiong.com/NewsImages/2012081218248259.jpg" /><a href="#">圖片標(biāo)題13</a></li>38 <li><img src="http://www.mitxiong.com/NewsImages/2012080621278799.jpg" /><a href="#">圖片標(biāo)題14</a></li>39 <li><img src="http://www.mitxiong.com/NewsImages/2012072907484455.jpg" /><a href="#">圖片標(biāo)題15</a></li>40 <li><img src="http://www.mitxiong.com/NewsImages/2012072521564314.jpg" /><a href="#">圖片標(biāo)題16</a></li>41 <li><img src="http://www.mitxiong.com/NewsImages/2012072507238259.jpg" /><a href="#">圖片標(biāo)題17</a></li>42 <li><img src="http://www.mitxiong.com/NewsImages/2012072409035684.jpg" /><a href="#">圖片標(biāo)題18</a></li>43 <li><img src="http://www.mitxiong.com/NewsImages/2012072219405236.jpg" /><a href="#">圖片標(biāo)題19</a></li>44 <li><img src="http://www.mitxiong.com/NewsImages/2012071218416980.jpg" /><a href="#">圖片標(biāo)題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) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離49 var w = document.documentElement.offsetWidth;//計(jì)算頁(yè)面寬度50 var ul = document.getElementById("flow-box");51 var li = ul.getElementsByTagName("li");52 var iw = li[0].offsetWidth + mh;//計(jì)算數(shù)據(jù)塊的寬度53 var c = Math.floor(w / iw);//計(jì)算列數(shù)54 ul.style.width = iw * c - mh + "px";//設(shè)置ul的寬度至適合便可以利用css定義的margin把所有內(nèi)容居中55 56 var liLen = li.length;57 var lenArr = [];58 for (var i = 0; i < liLen; i++) {//遍歷每一個(gè)數(shù)據(jù)塊將高度記入數(shù)組59 lenArr.push(li[i].offsetHeight);60 }61 62 var oArr = [];63 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數(shù)據(jù)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++) {//將其他數(shù)據(jù)塊定位到最短的一列后面,然后再更新該列的高度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() {//滾動(dòng)加載數(shù)據(jù)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;//為防止重復(fù)執(zhí)行,先清除事件88 _request(null, "GetList.php", function(data) {//當(dāng)滾動(dòng)到達(dá)最短的一列的距離時(shí)便發(fā)送ajax請(qǐng)求新的數(shù)據(jù),然后執(zhí)行回調(diào)函數(shù)89 _addItem(data.d, function() {//追加數(shù)據(jù)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;//執(zhí)行完成,恢愎onscroll事件 106 }); 107 }) 108 } 109 } 110 window.onscroll =scroll; 111 } 112 //圖片加載完成后執(zhí)行 113 window.onload = function() {flow(10, 10)}; 114 //改變窗口大小時(shí)重新布局 115 var re; 116 window.onresize = function() { 117 clearTimeout(re); 118 re = setTimeout(function() {flow(10, 10);}, 200); 119 } 120 //追加項(xiàng) 121 function _addItem(arr, callback) { 122 var _html = ""; 123 var a = 0; 124 var l = arr.length; 125 (function loadimg() { 126 var轉(zhuǎn)自:html5中國(guó)(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="#">圖片標(biāo)題1</a></li>26 <li><img src="http://www.mitxiong.com/NewsImages/2012112718241731.jpg" /><a href="#">圖片標(biāo)題2</a></li>27 <li><img src="http://www.mitxiong.com/NewsImages/2012111806582944.jpg" /><a href="#">圖片標(biāo)題3</a></li>28 <li><img src="http://www.mitxiong.com/NewsImages/2012110907231232.jpg" /><a href="#">圖片標(biāo)題4</a></li>29 <li><img src="http://www.mitxiong.com/NewsImages/2012110406319529.jpg" /><a href="#">圖片標(biāo)題5</a></li>30 <li><img src="http://www.mitxiong.com/NewsImages/2012101808066955.jpg" /><a href="#">圖片標(biāo)題6</a></li>31 <li><img src="http://www.mitxiong.com/NewsImages/2012101307276582.jpg" /><a href="#">圖片標(biāo)題7</a></li>32 <li><img src="http://www.mitxiong.com/NewsImages/2012082223432719.jpg" /><a href="#">圖片標(biāo)題8</a></li>33 <li><img src="http://www.mitxiong.com/NewsImages/2012082121509065.jpg" /><a href="#">圖片標(biāo)題9</a></li>34 <li><img src="http://www.mitxiong.com/NewsImages/2012081922387254.jpg" /><a href="#">圖片標(biāo)題10</a></li>35 <li><img src="http://www.mitxiong.com/NewsImages/2012081700252403.jpg" /><a href="#">圖片標(biāo)題11</a></li>36 <li><img src="http://www.mitxiong.com/NewsImages/2012081407597304.jpg" /><a href="#">圖片標(biāo)題12</a></li>37 <li><img src="http://www.mitxiong.com/NewsImages/2012081218248259.jpg" /><a href="#">圖片標(biāo)題13</a></li>38 <li><img src="http://www.mitxiong.com/NewsImages/2012080621278799.jpg" /><a href="#">圖片標(biāo)題14</a></li>39 <li><img src="http://www.mitxiong.com/NewsImages/2012072907484455.jpg" /><a href="#">圖片標(biāo)題15</a></li>40 <li><img src="http://www.mitxiong.com/NewsImages/2012072521564314.jpg" /><a href="#">圖片標(biāo)題16</a></li>41 <li><img src="http://www.mitxiong.com/NewsImages/2012072507238259.jpg" /><a href="#">圖片標(biāo)題17</a></li>42 <li><img src="http://www.mitxiong.com/NewsImages/2012072409035684.jpg" /><a href="#">圖片標(biāo)題18</a></li>43 <li><img src="http://www.mitxiong.com/NewsImages/2012072219405236.jpg" /><a href="#">圖片標(biāo)題19</a></li>44 <li><img src="http://www.mitxiong.com/NewsImages/2012071218416980.jpg" /><a href="#">圖片標(biāo)題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) {//參數(shù)mh和mv是定義數(shù)據(jù)塊之間的間距,mh是水平距離,mv是垂直距離49 var w = document.documentElement.offsetWidth;//計(jì)算頁(yè)面寬度50 var ul = document.getElementById("flow-box");51 var li = ul.getElementsByTagName("li");52 var iw = li[0].offsetWidth + mh;//計(jì)算數(shù)據(jù)塊的寬度53 var c = Math.floor(w / iw);//計(jì)算列數(shù)54 ul.style.width = iw * c - mh + "px";//設(shè)置ul的寬度至適合便可以利用css定義的margin把所有內(nèi)容居中55 56 var liLen = li.length;57 var lenArr = [];58 for (var i = 0; i < liLen; i++) {//遍歷每一個(gè)數(shù)據(jù)塊將高度記入數(shù)組59 lenArr.push(li[i].offsetHeight);60 }61 62 var oArr = [];63 for (var i = 0; i < c; i++) {//把第一行排放好,并將每一列的高度記入數(shù)據(jù)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++) {//將其他數(shù)據(jù)塊定位到最短的一列后面,然后再更新該列的高度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() {//滾動(dòng)加載數(shù)據(jù)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;//為防止重復(fù)執(zhí)行,先清除事件88 _request(null, "GetList.php", function(data) {//當(dāng)滾動(dòng)到達(dá)最短的一列的距離時(shí)便發(fā)送ajax請(qǐng)求新的數(shù)據(jù),然后執(zhí)行回調(diào)函數(shù)89 _addItem(data.d, function() {//追加數(shù)據(jù)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;//執(zhí)行完成,恢愎onscroll事件 106 }); 107 }) 108 } 109 } 110 window.onscroll =scroll; 111 } 112 //圖片加載完成后執(zhí)行 113 window.onload = function() {flow(10, 10)}; 114 //改變窗口大小時(shí)重新布局 115 var re; 116 window.onresize = function() { 117 clearTimeout(re); 118 re = setTimeout(function() {flow(10, 10);}, 200); 119 } 120 //追加項(xiàng) 121 function _addItem(arr, callback) { 122 var _html = ""; 123 var a = 0; 124 var l = arr.length; 125 (function loadimg() { 126
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/h-change/archive/2013/03/29/2989517.html
總結(jié)
以上是生活随笔為你收集整理的JavaScript实现自适应宽度的瀑布流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 多核运算
- 下一篇: JS 三级联动 下拉列表