瀑布流特点:
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'
}
]
}