使用position
排列图片,动态定位top
、left
1. 确定浏览器显示区域内,一行放多少列图片盒子(图片宽度一致,高度由内容撑开);
1.1 获取页面宽度
1.2 获取图片盒子宽度
1.3 显示的列数 = 页面宽度 / 图片盒子宽度
2. 确定列数之后,先排列第一行
2.1 显示的列数 = 页面宽度/(图片盒子宽度+间隙);
2.2 for
循环里判断 当i
(图片盒子的索引)小于column
(列数)的时候,说明在第一行
2.3 知道在第一行之后,动态设置每个盒子的left
值来排列第一行
left = i * ( itemWidth + gap );
3. 第一行排好之后,获取第一行所有图片盒子的高度
3.1 定义一个空数组,放高度,第二行的top
值需要根据第一行的高度来设置
3.2 获取图片高度的时候要注意,程序必须写在入口函数onload
里面,因为图片的加载特性是:等页面都加载完之后才去请求加载,所以不写在入口函数里可能会出现高度获取不到的情况。
4. 通过定位的方式排列第二行
4.1 获取到刚刚数组中,高度最小的那一列,将第2行的第1个图片盒子放置在它的下方;
4.2 此时的left
值就是高度最小列的offsetLeft
;top
值就是:第1行高度最小列的高度(为了布局美观可以加上上下间隙gap)。
4.3记录下高度最小列的索引index,后面计算会用到;
4.4 设置完成之后,会发现后面所有的图片都叠在这个高度最小列的下面,原因就是此时的最小列高度没有改变,应该加上下面图片的高度,得出一个新高度。
4.5 此时的这一列高度其实已经发生改变了,所以需要将新高度赋值给数组 当前高度最小列的高度 = 当前高度最小列的高度 + 间隙 + 下面图片盒子的高度
5. 触发resize事件
将整个设置样式的部分封装成一个函数,在onload里面注册一个resize事件,只要页面一发生改变,就触发样式部分的代码。实时改变pageWidth
的宽度,这样瀑布流就会是一个响应式的效果了。
6.懒加载效果
6.1 目前我们用的是30张图片,假如一个页面中有几百张图片的时候,我们不可能等到它都加载完再显示,所有这里引入一个懒加载的概念,我们规定第30张为显示的最后一张图片,当滚动条滚动到30张的时候,应该加载下一批图片。
6.2 即页面可视区高度+滚动条卷去的高度 = 第30图片的offsetTop;的时候加载下面的图片。
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
position: relative;
}
img {
width: 220px;
display: block;
}
.item {
position: absolute;
box-shadow: 2px 2px 2px #999999;
}
</style>
</head>
<body>
<div id="box">
<div class="item"><img src="images/1.jpg" alt=""></div>
<div class="item"><img src="images/2.jpg" alt=""></div>
<div class="item"><img src="images/3.jpg" alt=""></div>
<div class="item"><img src="images/4.jpg" alt=""></div>
<div class="item"><img src="images/5.jpg" alt=""></div>
<div class="item"><img src="images/6.jpg" alt=""></div>
<div class="item"><img src="images/7.jpg" alt=""></div>
<div class="item"><img src="images/8.jpg" alt=""></div>
<div class="item"><img src="images/9.jpg" alt=""></div>
<div class="item"><img src="images/10.jpg" alt=""></div>
<div class="item"><img src="images/11.jpg" alt=""></div>
<div class="item"><img src="images/12.jpg" alt=""></div>
<div class="item"><img src="images/13.jpg" alt=""></div>
<div class="item"><img src="images/14.jpg" alt=""></div>
<div class="item"><img src="images/15.jpg" alt=""></div>
<div class="item"><img src="images/16.jpg" alt=""></div>
<div class="item"><img src="images/17.jpg" alt=""></div>
<div class="item"><img src="images/18.jpg" alt=""></div>
<div class="item"><img src="images/19.jpg" alt=""></div>
<div class="item"><img src="images/20.jpg" alt=""></div>
<div class="item"><img src="images/21.jpg" alt=""></div>
<div class="item"><img src="images/22.jpg" alt=""></div>
</div>
<script>
var box = document.getElementById("box");
var items = box.children;
var gap = 10;
window.onload = function ( ) {
waterFall();
function waterFall() {
var pageWidth = getClient().width;
var itemWidth = items[0].offsetWidth;
var columns = parseInt(pageWidth/(itemWidth + gap));
var arr = [];
for(var i = 0; i<items.length; i++){
if (i < columns) {
items[i].style.top = 0;
items[i].style.left = (itemWidth + gap) * i + "px";
arr.push(items[i].offsetHeight);
}else {
var minHeight = arr[0];
var index = 0;
for(var j = 0; j<arr.length; j++){
if(minHeight > arr[j]) {
minHeight = arr[j];
index = j;
}
}
items[i].style.top = arr[index] + gap +"px";
items[i].style.left = items[index].offsetLeft + "px";
arr[index] = arr[index] + items[i].offsetHeight + gap;
}
}
}
window.onresize = function () {
waterFall();
};
window.onscroll = function ( ) {
if (getClient().height + getScrollTop() >= items[items.length - 1].offsetTop) {
var datas = [
"images/1.jpg",
"images/2.jpg",
"images/3.jpg",
"images/4.jpg",
"images/5.jpg",
"images/6.jpg",
"images/7.jpg",
"images/8.jpg",
"images/9.jpg",
"images/10.jpg",
"images/11.jpg",
"images/12.jpg",
"images/13.jpg",
"images/14.jpg",
"images/15.jpg",
"images/16.jpg",
"images/17.jpg",
"images/18.jpg",
"images/19.jpg",
"images/20.jpg",
"images/21.jpg",
"images/22.jpg",
];
for (var i = 0; i < datas.length; i++) {
var div = document.createElement("div");
div.className = "item";
div.innerHTML = '<img src="' + datas[i] + '" alt="">';
box.appendChild(div);
}
waterFall();
}
};
};
function getClient() {
return {
width:window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
height:window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
}
function getScrollTop() {
return window.pageYOffset || document.documentElement.scrollTop;
}
</script>
</body>
</html>