瀑布流又称瀑布流式布局,是比较流行的一种网站页面布局方式。视觉表现为参差不齐的多栏布局,最早采用此布局的是网站是 Pinterest,后逐渐在国内流行。
瀑布流布局效果
即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。
那么规则是什么呢?
下面通过图解来分析一下瀑布流的算法。
图解瀑布流算法
当第一排排满足够多的等宽图片时(如下图情况),自然而然的考虑到之后放置的图片会往下面排放。
那么第六张图片,放置在什么位置呢?是下图的位置么?
我们通过瀑布流算法实验得到,后面紧跟的第六张图片的位置应该是这个位置。
为什么呢?
因为放置它之前,这一列的高度为所有列中最小,所以会放置在这个地方。
所以我们知道了,如果再继续放置下去,第七张图片应该是这个位置,对吗?
通过瀑布流算法实验得出位置正确。看懂这个图示应该就能理解了瀑布流的原理算法。
JS 实现代码
window.onload = function () {
var wapper = document.querySelector('.wapper')
window.onscroll = function () { //滚动条事件
if (isOk()) { //判断可以执行图片时
for (var i in data.dataimg) { //循环数据库写入
wapper.innerHTML += ` <div class="box">
<div class="plic">
<img src="./images/${data.dataimg[i].src}.jpg" alt="">
</div>
</div>`
}
shunxu() //调用排序方式
}
}
shunxu()
function shunxu() { //封装图片排列顺序
var wapper = document.querySelector('.wapper');
var html_w = document.documentElement.clientWidth || document.body.clientWidth; //获取页面宽度
var boxs = document.querySelectorAll('.box');
var box_w = boxs[0].offsetWidth; //获取单张图片的宽度
var cols = Math.floor(html_w / box_w); //计算第一排的图片数量
wapper.style.width = box_w * cols + 'px'; //重新给wapper定义宽度
var arr = []; //声明一个空数组,放第一排图片的高度
for (var i = 0; i < boxs.length; i++) { //循环所有图片
if (i < cols) { //判断第一排的图片
arr.push(boxs[i].offsetHeight); //高度放入空数组
} else { //反之不是第一排的
var minH = Math.min.apply(Math, arr); //最低高度(数组找最小数的方法)
var ind = arr.indexOf(minH); //通过高度找出下标
boxs[i].style = `position:absolute;left:${ind * box_w}px;top:${minH}px`;
//定位,left值为下标*图片的宽度,top值为最低高度
arr[ind] += boxs[i].offsetHeight;
//加入图片后更新arr的数据
}
}
}
function isOk() { //封装图片是否要加载
var boxs = document.querySelectorAll('.box');
var screen_h = document.documentElement.clientHeight || document.body.clientHeight; //可视区窗口高度
var scroll_t = document.documentElement.scrollTop || document.body.scrollTop; //滚动条高度
var top = screen_h + scroll_t; //top值
var last_img = boxs[boxs.length - 1].offsetTop + boxs[boxs.length - 1].clientHeight / 2;//最后一张图片距顶部的高度
//总top值大于最后一张图片距顶部的高度吗,大于了就true,否则false
return top > last_img ? true : false;
}
}