图片瀑布流
首先,什么是图片瀑布流?
如下图,现实中我们的图片宽高大小不是总是一致的,但是在既不想过分损失图片质量情况下,又能最大化利用空间,该怎么实现呢,一般有两种方案
一种是宽固定,高度自适应(每一列的宽度都是一样的,下图是三列),如下图:
___________________图片来源于百度,侵权请告知!_________________
一种是高固定,宽自适应(每一行高都是一样的,下图是三行),如下图:
很早之前就知道了图片瀑布流,但是一直没有想着去实现一个,今天一起来实现一下吧,锻炼我们的逻辑思维(以宽固定为例)
因为整体逻辑比较简单,所以直接在代码注释中解释了 ^ _ ^
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
background: #999;
}
* {
margin: 0;
padding: 0;
}
.all {
background-color: rgba(255, 255, 255, 0.5);
width: 1090px;/* 父元素的宽固定*/
margin: auto;
margin-top: 20px;/*整体到顶部的距离,为了好看点*/
font-size: 0;/*消除图片间隙*/
position: relative;/*给父级一个绝对定位,这样子元素就可以相对他定位*/
}
.smallimg {
position: absolute;/*子元素开启相对定位*/
width: 200px;/*子元素的宽固定为200*/
}
</style>
</head>
<body>
<div class="all">
</div>
<script>
//定义一个img数组,模仿图片数据源
var img = ["01.jpg", "02.jpg", "03.jpg", "person.jpg", "pyy.jpg", "06.jpg", "03.jpg", "04.png", "05.jpg", "06.jpg"];
var all = document.getElementsByClassName("all")[0];//先获取到瀑布流的父级元素
var num = 5;//确定一行可以放多少个
var total = 50;//初始要生成的图片数量
//初始创建50张图片
createEle(total);
window.onload = function(ev) {
//给50张图片设置定位
setPosition(0);
//获取页面的高并赋值
var maxHeight = getMaxHeight(total);//获取创建完图片后的子元素的 总高(最上面的图片top到最下面的图片bottom),最大是多少,防止父级包不住
all.style.height = maxHeight + "px";//把总高赋值给父级
}
function createEle(newTotal) {
//创建对象函数
for (var i = newTotal - 50; i < newTotal; i++) {
var image = document.createElement("img");
image.src = "images/" + img[Math.floor((Math.random() * num))];
image.setAttribute("class", "smallimg"); //image.className = "smalling"
all.appendChild(image);
}
}
//关键函数,给图片设置定位
function setPosition(start) {
//设置图片定位函数
for (var i = start; i < all.children.length; i++) {
//因为子元素都是相对定位,所以设置偏移量就可以改变位置
//i % num 表示的是 一行最多只放五个,现在这个图片是这一行的第 i % 5 个,num等于5不变
// 知道是第几,那么左边的偏移量就是单个偏移的多少倍,比如第一个偏移 1 * 210 ,第二个偏移 2 * 210……
all.children[i].style.left = ((i % num) * 210) + "px";
// 当i > 5了,表示现在开始是第二行以后了,这时高度也高不断变化了,因为宽虽然固定,但是每个图片的高度不是一样的,要进行计算,再确定当前图片的应处于的高度
if (i >= num) {
//all.children[(i - num)].offsetHeight这个意思其实就是获取当前这个位置的 上面那张图片的高度
// all.children[(i - num)].offsetTop这个意思是获取当前这个位置的 上面那张图片距离顶部的距离
//再加上 间距10 就是应有的高度了
all.children[i].style.top = (all.children[(i - num)].offsetHeight + 10 + all.children[(i - num)].offsetTop) + "px";
} else {
//如果是第一行,那么高度就都是距离父级10px
all.children[i].style.top = "10px";
}
}
}
function getMaxHeight(newTotal) {
//在创建完所有图片后获取all的最后十个子元素,并比较其自身高与距离顶部的高
var max = 0
for (var i = newTotal - 10; i < newTotal; i++) {
// all.children[i].offsetTop 当前图片距离父级顶部的距离
//all.children[i].offsetHeight当前图片的高度
var temp = all.children[i].offsetTop + all.children[i].offsetHeight
if (temp > max) {//在最后十张图片中,不断更新最大值
max = temp
}
}
return max
}
this.addEventListener("scroll", function(evt) {
// document.documentElement.clientHeight可视区的高度
// document.body.offsetHeight 是body的总高度
if (document.documentElement.clientHeight + this.scrollY >= document.body.offsetHeight - 20) {//经典滚动事件中的判断方法
total = total + 50;//追加50张图片
createEle(total);//再创建50张图片
setPosition(total - 50)//设置后面50张的位置
all.style.height = getMaxHeight(total) + "px";
}
});
</script>
</body>
</html>
对于上我的理解,大家肯定有点晕,也不知道我说的是什么,那么就配合下面这个图一起理解吧!
瀑布流逻辑还是比较简单的,但是可以很好的锻炼我们的逻辑思维和加强对于js中的各种坐标的理解
有问题请私信哈!@ _ @
看都看完了,一键三连再走呗,嘿嘿嘿😁