JS 瀑布流布局
今天我们来介绍一个流行的图片布局方式,常见于个人博客,以及一些图片素材网站上。
瀑布流是一种形象的称呼,大小不一的盒子就像拼图一样,一个个拼接而成,形成一个“瀑布”。
效果图
原理
html 部分我们将盒子设置为定位。子绝父相布局。
JS 部分我们可以将图片分成 3 列,当图片铺完第一行之后,我们设置left:0
,从左边开始,利用判断语句查询最小高度的那一列,然后将图片放置到那一列。如此往复,就像拼图一样,瀑布流就产生了。
代码
<div class="all" id="all">
<div class="imgbox">
<img src="1.jpg" alt="" />
<div class="article">
要陪在值得的人身边一年又- -年十年又十年 愿去年所有的遗憾是今年惊喜的铺垫
一眨眼就2021年了早知道我不眨眼了 2020实鼠不易,2021牛转乾坤。
往后的日子是崭新的,谁也别回头看了。 有苦有甜才是生活,有悲有喜才是人生。
凛冬散尽,星河长明,新的一年,万事顺遂。
</div>
</div>
<div class="imgbox">
<img src="20201215095457_4bbec.jpg" alt="" />
<div class="article">
事事有找落,件件有回音。 银河有迹可循,2020年的不快乐要后会无期。
万物更新,旧疾当愈,长安常安。 如同梁.上燕岁岁常相见
看我的大长腿一不小心跨了个年 我和你跨过分秒,愿也可以跨过余生岁月
即使年年不见也要岁岁平安
</div>
</div>
<!-- imgbox都是一样的,只是内容不一样,所以这里省略部分代码 -->
</div>
* {
margin: 0;
padding: 0;
}
body {
width: 100%;
background-color: #eee;
font-size: 10px;
}
.all {
width: 87em;
position: relative;
margin: 10px auto 0;
}
.imgbox {
width: 29em;
background-color: #fafafa;
box-sizing: border-box;
position: absolute;
box-shadow: 0 0 10px #999;
}
img {
width: 29em;
display: block;
}
.article {
width: 23em;
font-size: 0.8em;
line-height: 2.6em;
margin: 30px auto;
}
html 与 css 都是基础知识,应该都看得懂,我就不再赘述了。
function waterfall() {
// 自动计算图片+文字内容宽度
var imgbox = document.getElementsByClassName('imgbox');
var margin_top = 5; //第一列margin-top
var margin_top2 = 5; //第二列margin-top
var margin_top3 = 5; //第三列margin-top
var arr = [0, 0, 0];
for (var i = 0; i < imgbox.length; i++) {
//获取最短的那一列的值
var min = Math.min.apply(null, arr);
// 获取它所在列
var column = arr.indexOf(min);
//如果在第一列
if (column == 0) {
arr[column] = min + imgbox[i].offsetHeight; //记录第一列高度
imgbox[i].style.left = '0px'; //设置style样式
//设置除第一行外的imgbox多往下挪动5px(产生点间隙,单纯为了美观)
if (i > 2) {
imgbox[i].style.top =
arr[column] - imgbox[i].offsetHeight + margin_top + 'px';
margin_top = margin_top + 5;
}
} else if (column == 1) {
arr[column] = min + imgbox[i].offsetHeight; //记录第二列高度
imgbox[i].style.left = imgbox[i - 1].offsetWidth + 5 + 'px';
if (i > 2) {
imgbox[i].style.top =
arr[column] - imgbox[i].offsetHeight + margin_top2 + 'px';
margin_top2 = margin_top2 + 5;
}
} else if (column == 2) {
arr[column] = min + imgbox[i].offsetHeight; //记录第三列高度
imgbox[i].style.left =
imgbox[i - 1].offsetWidth + imgbox[i - 2].offsetWidth + 10 + 'px';
if (i > 2) {
imgbox[i].style.top =
arr[column] - imgbox[i].offsetHeight + margin_top3 + 'px';
margin_top3 = margin_top3 + 5;
}
}
}
}
//加载完成后执行。
window.onload = function () {
waterfall();
};
思路:
1、我们需要获取<div class=imgbox></div>
的大小,利用offsetWidth
与offsetHeight
.
2、定义一个数组arr=[0,0,0]
,3 个数代表 3 列,每一列高度从 0 开始。
利用数组记录每一列的高度,然后利用Math.min.apply()
方法去找出数组中最小的数,再去寻找最小值所在下标,可以用indexOf()
方法,找出来的下标对应的即是所在列数 (列数从 0 开始数!)。
3、利用循环,给每一列的每一个元素设置 style 样式。
注释我都添加在了每一行代码后边,大家自己练习的时候可以先在纸上写个大纲,免得写的时候逻辑混乱。