瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。
目标知识点:
- 复习
定位
与offset家族
; - 学习
scroll家族
- 练习
方法的调用
代码:
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>瀑布流</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div id="main">
<div class="box"><div class="pic"><img src="images/img01.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img02.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img03.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img04.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img05.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img06.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img07.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img08.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img09.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img10.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img01.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img02.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img03.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img04.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img05.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img06.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img07.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img08.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img09.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img10.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img01.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img02.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img03.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img04.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img05.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img06.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img07.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img08.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img09.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img10.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img01.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img02.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img03.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img04.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img05.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img06.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img07.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img08.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img09.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img10.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img01.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img02.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img03.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img04.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img05.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img06.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img07.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img08.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img09.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img10.jpg" alt=""></div></div>__
</div>
<!--引入underscore库,只在求min(array)中用到-->
<script src="js/underscore.js"></script>
<script src="js/myScrollFunc.js"></script>
<script src="js/index.js"></script>
</body>
</html>
css:
* {
margin: 0;
padding: 0;
border: none;
}
img {
vertical-align: top;
}
html, body {
width: 100%;
height: 100%;
}
#main {
position: relative;
}
.box {
float: left;
padding: 15px 0 0 15px;
}
.pic {
padding: 10px;
border: 1px solid #cccccc;
border-radius: 5px;
}
.pic img {
width: 165px;
}
js:
- myScrollFunc:
/**
* 获取滚动的头部距离和左边距离
* scroll().top scroll().left
* @returns {*}
*/
function scroll() {
if(window.pageYOffset !== null){
return {
top: window.pageYOffset,
left: window.pageXOffset
}
}else if(document.compatMode === "CSS1Compat"){ // W3C
return {
top: document.documentElement.scrollTop,
left: document.documentElement.scrollLeft
}
}
return {
top: document.body.scrollTop,
left: document.body.scrollLeft
}
}
- index.js
window.onload = function () {
//第一次布局
waterFull("main", "box");
//动态加载图片
window.onscroll = function () {
if (checkWillLoadImage()) {
//造数据
var dataArr = [
{"src": "img01.jpg"},
{"src": "img02.jpg"},
{"src": "img03.jpg"},
{"src": "img04.jpg"},
{"src": "img05.jpg"},
{"src": "img06.jpg"},
{"src": "img07.jpg"},
{"src": "img08.jpg"},
{"src": "img09.jpg"},
{"src": "img10.jpg"}
];
//创建元素
for (var i = 0; i < dataArr.length; i++) {
var newBox = document.createElement("div");
newBox.className = "box";
$("main").appendChild(newBox);
var newPic = document.createElement("div");
newPic.className = "pic";
newBox.appendChild(newPic);
var newImg = document.createElement("img");
newImg.src = "images/" + dataArr[i].src;
newPic.appendChild(newImg);
}
//重新加载布局
waterFull("main", "box");
}
}
};
/**
* 实现瀑布流布局
* @param parent 父盒子id,relative定位
* @param child 子盒子class
*/
function waterFull(parent, child) {
// 1 让父盒子居中
// 1.1 获取所有的子盒子
var allBox = $(parent).getElementsByClassName(child);
// 1.2 获取子盒子的宽度
var boxWidth = allBox[0].offsetWidth;
// 1.3 获取屏幕的宽度
var screenW = document.documentElement.clientWidth;
// 1.4 计算出当前有几列
var cols = parseInt(screenW / boxWidth);
// 1.5 计算出父盒子的宽度 使居中
$(parent).style.width = cols * boxWidth + "px";
$(parent).style.margin = "0 auto";
// 2 子盒子的定位 先找当前最高的空位
// 2.1 定义高度数组,遍历到的某一个盒子高度,最高可嵌入高度,可嵌入高度的列数
var heightArr = [], boxHeight = 0, minBoxHeight = 0, minBoxIndex = 0;
// 2.2 遍历子盒子
for (var i = 0; i < allBox.length; i++) {
// 2.2.1 求出每个子盒子高度
boxHeight = allBox[i].offsetHeight;
// 2.2.2 取出第一行盒子的高度放入高度数组
if (i < cols) {
heightArr.push(boxHeight);
} else {// 剩余行
// 取出最高空位的x值
minBoxHeight = _.min(heightArr);
// 求出这个空位的列数
minBoxIndex = getMinBoxIndex(heightArr, minBoxHeight);
//定位要嵌入的子盒子
allBox[i].style.position = "absolute";
allBox[i].style.left = minBoxIndex * boxWidth + "px";
allBox[i].style.top = minBoxHeight + "px";
//每次嵌入后更新高度
heightArr[minBoxIndex] += boxHeight;
}
}
}
/**
* 求出最高空位的列数
* @param arr 在哪个数组中找
* @param val 要查找的空位的高度
*/
function getMinBoxIndex(arr, val) {
for (var i = 0; i <= arr.length; i++) {
if (arr[i] === val) {
return i;
}
}
}
function $(id) {
return typeof id === "string" ? document.getElementById(id) : null;
}
/**
* 判断是否可以继续嵌入图片
* @returns {boolean}
*/
function checkWillLoadImage() {
//获取最后一个盒子
var allBox = document.getElementsByClassName("box");
var lastBox = allBox[allBox.length - 1];
//求出最后一个盒子自身高度的一半 + offsetTop
var lastBoxDis = lastBox.offsetHeight * 0.5 + lastBox.offsetTop;
//求出屏幕的高度
var screenW = document.body.clientHeight || document.documentElement.clientHeight;
//求出页面偏离浏览器的高度
var scrollTop = scroll().top;
return lastBoxDis <= screenW + scrollTop;
}
体会:
原生js做瀑布流真的有点麻烦 = =