前言
本前端渣在今天的学习中遇到了一种新的布局方式--瀑布流布局。那么什么是瀑布流布局呢?(一个熊猫图在我脑海中浮现)
瀑布流布局
当前主流的一些软件当中我们常常可以看见这样的一种布局,该布局可以将大小不一的图片完整的显示在页面上,并且在杂乱的布局中保持着一定的美感。(如下图:)
HTML与CSS部分
- div#container 作为所有图片的容器
- div.box 作为每个图片的容器
- div.box-img 包裹 img 标签
- img负责显示图片
- 多个 div.box 排列图片
- 重复上述结构,排列了多行图片
- 主容器使用相对定位占据文档流中的位置而其子标签box使用浮动式布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#container {
position: relative;
}
.box {
float: left;
padding: 5px;
}
.box-img {
width: 150px;
padding: 5px;
border: 1px solid #dd9f9f;
}
img {
width: 100%;
}
</style>
</head>
<body>
<div id="container">
<div class="box">
<div class="box-img">
<img src="./img/1.webp" alt="">
</div>
</div>
......省略了19个box
</div>
<script src="index.js"></script>
</body>
</html>
此时的页面:
JavaScript部分
实现原理:
1.使用一个父容器container包裹子容器box
2.图片容器box-img包裹在容器box中,用来展示
3.通过js获取父容器的DOM结构,再获取其子元素图片容器box
4.将其按照瀑布流的规则使用绝对定位放置
5.获取屏幕大小计算该屏幕最多能放下几张图片,将前n张图片放在第一行
6.使用一个heightArr高度数组,在放置的时候记录每一列图片的高度,后面的图片放置在高度最低的那一列
图解:
js代码实现:
//获取用户屏幕宽度,决定一行几张图
//操作下一张图,放到上一行最矮的列下
imgLocation('container', 'box');
function imgLocation(parent, content) {
var cparent = document.getElementById(parent)
var ccontent = getChildElement(cparent, content) //document.querySelectorAll('#container .box')
// console.log(ccontent)
var imgWidth = ccontent[0].offsetWidth
var num = Math.floor(document.documentElement.clientWidth / imgWidth)
cparent.style.width = `${imgWidth * num}px`
//要操作的是哪张,每一列的高度
var BoxHeightArr = []
for (var i = 0; i < ccontent.length; i++) {
if (i < num) {
//记录第一行
BoxHeightArr[i] = ccontent[i].offsetHeight
}
else {
//开始操作,找到最矮的高度及列数
minHeight = Math.min.apply(null, BoxHeightArr)
var minIndex = BoxHeightArr.indexOf(minHeight);
//摆放图片位置
ccontent[i].style.position = "absolute"
ccontent[i].style.top = minHeight + "px"
ccontent[i].style.left = ccontent[minIndex].offsetLeft + "px"
//更新这一列图片高度
BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight
}
}
console.log(BoxHeightArr);
}
function getChildElement(parent, child) {
//获取parent中所有child
var childArr = []
var allChild = parent.getElementsByTagName('*')
//找出所有box
for (var i = 0; i < allChild.length; i++) {
if (allChild[i].className == child) {
childArr.push(allChild[i])
}
}
return childArr
}
最终效果:
到这瀑布流布局就已经实现了,希望对大家有所帮助。