今天抽空再写一篇,写个瀑布流的效果。做过iOS的都知道瀑布流在iOS中也是个很流行的布局方式,这里就不再多介绍了。我们来看看如何用JS来实现瀑布流的效果。
我就直接上代码了,里面的注释都很清晰。不懂的可以来问我。
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>瀑布流效果</title>
<link href="css/index.css" rel="stylesheet">
</head>
<body>
<!--父标签-->
<div id="main">
<div class="box">
<div class="pit">
<img src="images/0.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/1.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/2.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/3.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/4.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/5.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/6.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/7.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/8.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/9.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/10.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/11.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/12.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/13.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/14.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/15.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/16.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/17.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/18.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/19.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/20.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/21.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/22.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/23.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/24.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/25.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/26.jpg">
</div>
</div>
<div class="box">
<div class="pit">
<img src="images/27.jpg">
</div>
</div>
</div>
<script src="js/index.js" type="text/javascript"></script>
</body>
</html>
CSS:
a, address, b, big, blockquote, body, center, cite, code, dd, del, div, dl, dt, em, fieldset, font, form, h1, h2, h3, h4, h5, h6, html, i, iframe, img, ins, label, legend, li, ol, p, pre, small, span, strong, u, ul, var{
padding: 0;
margin: 0;
}
#main {
position: relative;
}
#main .box {
padding: 15px 0 0 15px;
float: left;
}
#main .box .pit {
padding: 5px;
border: 1px solid #ddd;
border-radius: 5px;
box-shadow: 0 0 2px gray;
width: 165px;
}
#main .box .pit img {
width: 165px;
}
JS:
/**
* Created by huminghao on 2017/7/5.
*/
function $(id) {
return typeof id === 'string' ? document.getElementById(id) : id;
}
// 当页面加载完毕
window.onload = function () {
// 实现瀑布流
waterFlow('main', 'box');
// 监听页面的滚动
window.onscroll = function () {
// 判断是否具备加载图片的条件
if (checkWillLoadImg()) {
// 造数据
var dataImg = {'data' : [{'src' : '0.jpg'}, {'src' : '1.jpg'},{'src' : '2.jpg'},{'src' : '3.jpg'},{'src' : '4.jpg'},{'src' : '5.jpg'},{'src' : '6.jpg'},{'src' : '7.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'}]}
for (var i = 0; i < dataImg.data; 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/' + dataImg.data[i].src;
newPic.appendChild(newImg);
}
}
}
}
// 实现瀑布流
function waterFlow(parent, box) {
// 让所有盒子的父标签居中
// 1.拿到所有的盒子
var allBoxs = $(parent).getElementsByClassName(box);
// 2.拿到其中一个盒子的宽度
var boxWidth = allBoxs[0].offsetWidth;
// 3.求出页面的宽度
var screenWidth = document.body.clientWidth;
// 4.求出列数
var clos = Math.floor(screenWidth / boxWidth);
// 5.让父标签居中
$(parent).style.cssText = 'width: ' + clos * boxWidth + 'px; margin: 0 auto';
// 定位
// 定义一个高度数组
var heightArray = [];
// 遍历
for (var i = 0; i < allBoxs.length; i ++) {
// 求出所有盒子的高度
var boxHeight = allBoxs[i].offsetHeight;
if (i<clos) { // 第一行
heightArray.push(boxHeight);
console.log(heightArray);
}else { // 剩余行
// 取出最矮盒子
var minBoxHeight = Math.min.apply(null, heightArray);
// 取出最矮盒子对应的索引
var minBoxIndex = getMinIndex(minBoxHeight, heightArray);
// 对剩余的盒子进行定位
allBoxs[i].style.position = 'absolute';
allBoxs[i].style.top = minBoxHeight + 'px';
allBoxs[i].style.left = minBoxIndex * boxWidth + 'px';
// 替换高度
heightArray[minBoxIndex] = minBoxHeight + boxHeight;
}
}
}
// 求出最矮盒子在数组中的索引
function getMinIndex(value, array) {
for (var i = 0; i < array.length; i ++) {
if (value == array[i]) {
return i;
}
}
}
// 判断是否具备加载图片的条件
function checkWillLoadImg() {
// 拿到所有的盒子
var allBoxs = $('main').getElementsByClassName('box');
// 取出最后一个盒子
var lastBox = allBoxs[allBoxs.length - 1];
// 求出最后一个盒子高度的一半 + 头部偏移的位置
var lastBoxHeightDis = lastBox.offsetHeight * 0.5 + lastBox.offsetTop;
// 求出屏幕的高度
var screenHeight = document.body.clientHeight || document.documentElement.clientHeight;
// 求出页面偏离浏览器的高度
var offSetTop = document.body.offsetTop || document.documentElement.offsetTop;
console.log(lastBoxHeightDis, screenHeight, offSetTop);
return lastBoxHeightDis < (offSetTop + screenHeight) ? true : false;
}
最后的效果大家可以去我的github下载查看:https://github.com/kiddhmh/HTML-Demo