瀑布流:每個內(nèi)容的寬度相等,高度是隨機的
布局的基本原則,第一排排滿之后,下面的元素將放到高度最短的那一列下面。
實現(xiàn)的基本思路:
- 需要創(chuàng)建一個數(shù)組,這個數(shù)組存儲的每一項都為對應(yīng)列的高度,而下標(biāo)就為當(dāng)前的列
- 需要得到每個元素的寬度
實現(xiàn)舉例:
<style>
.content {
position: relative;
}
.item {
/*絕對定位,并且每個元素的寬度是一定的*/
position: absolute;
width: 200px;
margin-right: 10px;
margin-top: 10px;
transition: all 1s;
}
.h1 {
height: 200px;
background: #f4b300;
}
.h2 {
height: 300px;
background: #691bbb;
}
.h3 {
height: 400px;
background: #006ac1;
}
</style>
</head>
<body>
<div class="content">
<div class="item h1">1</div>
<div class="item h3">2</div>
<div class="item h2">3</div>
<div class="item h2">4</div>
<div class="item h3">5</div>
<div class="item h1">6</div>
<div class="item h2">7</div>
<div class="item h3">8</div>
<div class="item h1">9</div>
<div class="item h2">10</div>
<div class="item h3">11</div>
<div class="item h3">12</div>
<div class="item h2">13</div>
<div class="item h1">14</div>
</div>
結(jié)構(gòu)和樣式如上,h1,h2,h3用來模擬隨機的高度。
JS部分如下:
<script src="../jquery-3.2.1.min.js"></script>
<script>
// 創(chuàng)建數(shù)組
var itemArr = [];
//得到數(shù)組一共有多少項,即要排列的元素到底有幾列,可以通過content的寬度除以item的寬度,然后進(jìn)行取整就能得到總共有多少列
var itemColumn = parseInt($('.content').width() / $('.item').width());
// console.log(itemColumn)
//進(jìn)行數(shù)組的初始化,有itemColumn項,每項都先設(shè)為0,表示當(dāng)前沒有元素,高度為0
for (var i = 0; i < itemColumn; i ++) {
itemArr[i] = 0;
}
//數(shù)組初始化完畢,然后涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法
//進(jìn)行遍歷所有的item,將每個item放到當(dāng)前高度最短的那一列的下邊
$('.item').each(function () {
var minHeight = Math.min.apply(null,itemArr);//數(shù)組中值最小的一項,即高度最短的那一列的高度值
var minIndex = itemArr.indexOf(minHeight); // 對應(yīng)列的下標(biāo)
$(this).css({
left: minIndex * $('.item').outerWidth(true), //這個outerWidth,有true代表包括margin,不寫true代表只包括border
top: minHeight,
})
itemArr[minIndex] += $(this).outerHeight(true); //放置完當(dāng)前遍歷元素時,將相應(yīng)的高度加到當(dāng)前列的高度上
// console.log('h',minHeight)
// console.log('i',minIndex);
})
</script>
代碼的整體思路已經(jīng)很清晰了,但是有地方需要注意:
- 涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法。使用Math.min要結(jié)合apply()
- $('.item').outerWidth(true)
然后基本效果就達(dá)到了,但是需要監(jiān)聽窗口大小改變的事件,如果窗口大小改變,重新排列一下。所以我們封裝一下我們得到的代碼。加上監(jiān)聽事件
waterFall(); //頁面初始化時先執(zhí)行一次出現(xiàn)布局
$(window).on('resize',function () { // 監(jiān)聽瀏覽器窗口大小改變的事件
waterFall();
})
function waterFall() {
// 創(chuàng)建數(shù)組
var itemArr = [];
//得到數(shù)組一共有多少項,即要排列的元素到底有幾列,可以通過content的寬度除以item的寬度,然后進(jìn)行取整就能得到總共有多少列
var itemColumn = parseInt($('.content').width() / $('.item').width());
// console.log(itemColumn)
//進(jìn)行數(shù)組的初始化,有itemColumn項,每項都先設(shè)為0,表示當(dāng)前沒有元素,高度為0
for (var i = 0; i < itemColumn; i ++) {
itemArr[i] = 0;
}
//數(shù)組初始化完畢,然后涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法
//進(jìn)行遍歷所有的item,將每個item放到當(dāng)前高度最短的那一列的下邊
$('.item').each(function () {
var minHeight = Math.min.apply(null,itemArr);//數(shù)組中值最小的一項,即高度最短的那一列的高度值
var minIndex = itemArr.indexOf(minHeight); // 對應(yīng)列的下標(biāo)
$(this).css({
left: minIndex * $('.item').outerWidth(true), //這個outerWidth,有true代表包括margin,不寫true代表只包括border
top: minHeight,
})
itemArr[minIndex] += $(this).outerHeight(true); //放置完當(dāng)前遍歷元素時,將相應(yīng)的高度加到當(dāng)前列的高度上
// console.log('h',minHeight)
// console.log('i',minIndex);
})
}
此時窗口大小改變時也會相應(yīng)的重新布局了。還可以進(jìn)一步封裝代碼,創(chuàng)建一個對象,把要執(zhí)行的代碼return出來,函數(shù)體放到對象內(nèi)部的屬性中。
var begin = {
run: run,
};
begin.run();
function run () {
function waterFall() {
// 創(chuàng)建數(shù)組
var itemArr = [];
//得到數(shù)組一共有多少項,即要排列的元素到底有幾列,可以通過content的寬度除以item的寬度,然后進(jìn)行取整就能得到總共有多少列
var itemColumn = parseInt($('.content').width() / $('.item').width());
// console.log(itemColumn)
//進(jìn)行數(shù)組的初始化,有itemColumn項,每項都先設(shè)為0,表示當(dāng)前沒有元素,高度為0
for (var i = 0; i < itemColumn; i ++) {
itemArr[i] = 0;
}
//數(shù)組初始化完畢,然后涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法
//進(jìn)行遍歷所有的item,將每個item放到當(dāng)前高度最短的那一列的下邊
$('.item').each(function () {
var minHeight = Math.min.apply(null,itemArr);//數(shù)組中值最小的一項,即高度最短的那一列的高度值
var minIndex = itemArr.indexOf(minHeight); // 對應(yīng)列的下標(biāo)
$(this).css({
left: minIndex * $('.item').outerWidth(true), //這個outerWidth,有true代表包括margin,不寫true代表只包括border
top: minHeight,
})
itemArr[minIndex] += $(this).outerHeight(true); //放置完當(dāng)前遍歷元素時,將相應(yīng)的高度加到當(dāng)前列的高度上
// console.log('h',minHeight)
// console.log('i',minIndex);
})
}
return (function () {
waterFall(); //頁面初始化時先執(zhí)行一次出現(xiàn)布局
$(window).on('resize',function () { // 監(jiān)聽瀏覽器窗口大小改變的事件
waterFall();
})
})();
}
封裝代碼如上所示,把函數(shù)體放到run()中,作為值傳遞給begin對象的run屬性,return的是包含我們想要執(zhí)行的代碼的立即執(zhí)行函數(shù),這樣我們想要開始的時候,只需要調(diào)用begin對象的run屬性即可。