前端軼事:奇妙的個性化瀑布流佈局

之前筆者做的項目中圖片的排布都是以div定寬高包裹,img設置100%。這樣在只有少量圖片的網站上有奇效——樣式簡單、佈局便捷。
以前一直爲發現了這一方法而“沾沾自喜”,但近來瀏覽了【百度圖片】網頁
。。。
莫名的就想到了【瀑布流佈局】


開篇

何爲瀑布流佈局

形似瀑布排列,通常來說高度不固定而 寬度固定(以達到頁面resize排列改變的效果),下一排圖片緊接着上一排放,如下:
pblbj


要達到這種效果,首先我們要分析圖片的排列特點:
上面說“下一行緊貼着上一行排列”,我們順着“上一行”網上找,發現了一個特殊的地方——第一行。
我們很容易知道,第一行就是整個【(圖片)瀑布流】的基礎/參照。
有了這個,我們又能得到——除了第一行,其餘的圖片都要進行position:absolute; 處理。也就是說,整個區域內,只有第一行圖片在文檔流內:知道這一點很重要。

我們繼續往下看,假如說現在我們有這樣一行:
2

並且設定了其高度分別爲100、120、200,寬度爲200,那麼下一行應該這樣排列:
3

我們可以發現一個規律:

position: absolute;
left: i*圖片寬度
top: 最小高度

如何求這個【最小高度】值呢?這可是解決的關鍵!
我們不妨將數據都放到數組中:

數組 [100,120,200]

配合【列數】,進行求解。


大致思路如此,讓我們一起來看下代碼:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>試驗圖片動態響應排列</title>
		<script src="../js/jquery.min.js"></script>
		<script src="../js/mxc.js"></script>
		<style>
			/* overflow:hidden;在此利用了BFC原理,使得大div邊框能包裹所有元素 */
			.mxc{width: 90%;border: 1px solid red;margin-left: 5%;overflow: hidden;}
			.mxc img{float: left;width: 90px;height: 60px;}
		</style>
	</head>
	<body>
		<div class="mxc">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/small_red_triangle_down.png" alt="" />
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smile.png" alt="" />
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smile_cat.png" alt="" />
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smiley.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smiley_cat.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smiling_imp.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smirk.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smoking.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/small_red_triangle_down.png" alt="" />
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smiliie.png" alt="" />
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smile_catbb.png" alt="" />
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smileycc.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smiley_catdd.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smiling_impee.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smiggrk.png" alt="">
			<img src="../Web項目實戰/app/src/components/inputBar/img/emoji/pngs/smokinghh.png" alt="">
		</div>
	</body>
</html>

因爲這裏用的jQuery,js文件中應該這樣寫:

$(function(){   //這是$(document).ready(function(){})的縮寫
	
})

在正式開始處理圖片之前,我們首先要獲取到需要的信息——寬度 & 列數:

var allBox=$(".mxc img")   //-- 如果每個圖片外有小div包裹,這裏改變
var boxWidth=allBox.outerWidth();   //一個img的寬度
var screenWidth=$(window).width();   //可見區域的寬
var cols=parseInt(screenWidth/boxWidth);   //列數
var heightArr=[];   //獲取高度的數組

然後去處理圖片:

$.each(allBox,function(index,item){
	var boxHeight=item.outerHeight();   //每張圖片高度 -- 如果每個圖片外有小div包裹,這裏item換成$(item)即可
	if(index < cols){
		heightArr[index]=boxHeight;
	}else{
		item.css({
			position:'absolute',
			left:i*boxWidth
			top:'最小高度'
		})
	}
	
})

這個 i 是什麼?=> 最小高度的索引。
那如何求出所謂“最小的i”?
我們首先想到的幾乎一定是【遍歷數組】了。
有沒有人會想到Math.min()函數呢?這可是個好工具:他能簡便的求出字符串中的最小值。
字符串?對了,我們得到的是數組!

沒關係,我們不是還有apply的嘛 —— apply,其主要作用是將第二個參數代入第一個參數中運算(因爲第一個參數通常是this,所以常用於this指針的重定向)

apply函數的第二個參數是數組

12

所以上面代碼中else部分可以改爲下面這樣:

var minBoxHeight=Math.min.apply(Math.min,heightArr);
var minHeightIndex=$.inArray(minBoxHeight,heightArr);   //jQuery中的求索引函數
item.css({   // -- 如果每個圖片外有小div包裹,這裏item換成$(item)即可
	position:'absolute',
	left:minHeightIndex*boxWidth+'px',
	top:minBoxHeight+'px'
})
//改變了寬高,我們要將“最小高度”進行更新
heightArr[minHeightIndex]+=boxHeight;

Tip:
outerWidth():不包含margin
innerWidth():不包含margin、border
width():不包含padding、margin、border

這樣,功能上算是完成了。但是當我們打開頁面,會發現每一次刷新都有可能有的地方會出現高度上的錯誤。
此時筆者的內心是懵逼的…

在筆者將代碼從上往下再從下往上看了一遍又一遍時,突然想到了頁面加載時圖片後於文檔流加載
啊呀,把這個忘了:我們應當把開頭的$(function(){}) 換成:

$(window).on('load',function(){
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章