瀑布流特點:
1. 瀑布流元素寬度相同,高度不同
2. 滾動頁面時,在頁面高度最小處插入元素
效果圖:
話不多說,直接上代碼
css:
* {
margin: 0;
padding: 0;
}
.box {
float: left;
padding: 0 5px;
}
.pic {
padding: 2px;
border-radius: 5px;
box-sizing: border-box;
}
.pic img {
width: 200px;
}
html:
/* box元素可以適當多複製一些,撐起scrollTop事件 */
<div id="main">
<div class="box">
<div class="pic"><img src="./img/set3/1.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/2.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/3.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/4.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/5.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/6.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/7.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/8.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/9.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/10.jpg" alt=""></div>
</div>
<div class="box">
<div class="pic"><img src="./img/set3/11.jpg" alt=""></div>
</div>
</div>
js:
/* 聲明需要的變量
oParent 父級容器
boxW 單個盒子寬度
col 屏幕一排顯示的列數
minHArr 各列數中,距離頂部的高度
*/
var oParent, boxW, col, minHArr;
window.onload = function () {
oParent = document.getElementById('main'); //獲取父容器
boxW = getAllBox(oParent, 'box')[0].clientWidth; //獲取單個盒子寬度
// 獲取屏幕中存在的列數
col = Math.floor(document.documentElement.clientWidth / boxW);
waterFall(oParent, 'box'); //頁面元素重排
window.onscroll = function () {
// 滾動時做極值判斷,是否到達底部
if (isBottom(oParent, 'box')) {
var fakerArr = fakerData(); //要加載的數據
for (var i = 0; i < fakerArr.length; i++) {
//動態創建dom結構,添加到頁面中
var oBox = document.createElement('div');
oBox.className = 'box';
var oPic = document.createElement('div');
oPic.className = 'pic';
var oImg = document.createElement('img');
oImg.src = fakerArr[i].img;
oPic.appendChild(oImg);
oBox.appendChild(oPic);
oParent.appendChild(oBox);
}
waterFall(oParent, 'box'); //頁面元素重排
}
}
// 改變屏幕寬度時,重新獲取列數
window.onresize = function () {
col = Math.floor(document.documentElement.clientWidth / boxW);
waterFall(oParent, 'box'); //頁面元素重排
}
}
function waterFall(oParent, className = 'box') {
var oBoxs = getAllBox(oParent, className);
minHArr = []; // 存儲各列數距離頂部的高度
for (var i = 0; i < oBoxs.length; i++) {
if (i < col) { // 第一排,爲float元素,不改變位置,獲取盒子高度
minHArr.push(oBoxs[i].clientHeight)
} else {
// 第二排時,取第一排最小高度值,定位過去
var minH = Math.min.apply(null, minHArr); // 此時一排最小高度
var minIndex = getLocationIndex(minHArr, minH); // 數組中的索引值
oBoxs[i].style.position = 'absolute'; //絕對定位
oBoxs[i].style.top = minH + 'px'; // 設置top值,爲數組最小高度
// 設置top值,索引 * 盒子寬度
oBoxs[i].style.left = minIndex * boxW + 'px';
// 元素定位排版後,重新設置此列高度值
minHArr[minIndex] = minH + oBoxs[i].clientHeight;
}
}
}
// 不直接用getElementsByClassName, 可能存在兼容性問題
function getAllBox(oParent, className = 'box') {
var allArr = oParent.getElementsByTagName('*');
var boxArr = [];
for (var i = 0; i < allArr.length; i++) {
if (allArr[i].className === className) {
boxArr.push(allArr[i])
}
}
return boxArr
}
// 獲取數組索引值, indexOf個別瀏覽器不兼容
function getLocationIndex(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === item) {
return i
}
}
}
function isBottom(oParent, className = 'box') {
// 重新獲取頁面中box數量
var oBoxs = getAllBox(oParent, className);
/* 獲取最後一盒子頭部距離頂部距離(最後一盒子offsetTop爲上一排盒子中距離頂部最小值) */
var lastBoxH = oBoxs[oBoxs.length - 1].offsetTop;
// 獲取滾動條捲去的高度
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// 獲取瀏覽器屏幕寬度
var clientH = document.documentElement.clientHeight || document.body.clientHeight;
//當能看到最後一盒子頭部時,返回true
return scrollTop + clientH >= lastBoxH ? true : false
}
function fakerData() {
return [{
img: './img/set3/1.jpg'
},
{
img: './img/set3/2.jpg'
},
{
img: './img/set3/3.jpg'
},
{
img: './img/set3/4.jpg'
},
{
img: './img/set3/5.jpg'
},
{
img: './img/set3/6.jpg'
},
{
img: './img/set3/7.jpg'
},
{
img: './img/set3/8.jpg'
},
{
img: './img/set3/9.jpg'
},
{
img: './img/set3/10.jpg'
},
{
img: './img/set3/11.jpg'
}
]
}