前言
前端有很多经典的布局,比如圣杯布局、弹性布局、多栏布局等,这几个布局相对而言比较简单,本节介绍的瀑布流布局也是一种经典布局,它的实现要复杂一点,如果你还不能手写一个瀑布流,那就一起来学习下。
瀑布流
含义
瀑布流布局的特点就是元素高度不一样,每一行元素有高有低,凸显出凌乱美,不像弹性布局那种规规矩矩的。这种布局适用于图片或内容的展示,比如:
实现
瀑布流看起来很乱,但它还是遵循着自己的规律,每次元素会插入到高度最低的一列,这是瀑布流核心思想,所以上述图例中元素插入顺序应该是:
这种方式能够有效的利用空间,瀑布流也相当于是性能优化的一种方式。要想实现瀑布流就抓住核心思路就行,具体方法也有好几种:
- 思路一:假设容器宽度等分为n列,然后动态计算每一列的高度,这里我们声明一个数组去保存每一列的高度,方便计算出最小高度列。将每个元素设为绝对定位,当元素插入的时候,根据最小列计算出位移数据,同时更新数组中的元素即可。
const heightArr = new Array(3).fill(0);
function waterfallLayout(item) {
// 获取最低高度的列数
const min = Math.min(...heightArr);
const minIndex = heightArr.findIndex((v) => v === min);
// 获取位移数据
const top = heightArr[minIndex];
const left = minIndex * item.clientWidth;
//将元素位置进行位移
item.style.transform = `translate(${top}px,${left}px)`;
// 更新高度
heightArr[minIndex] = top + item.offsetHight;
}
该思路适用于vue中,结合v-for动态去计算每个元素位置
- 思路二:首先获取列的dom集合,初始化一个最小列的元素,然后对比出最小列,将需要插入的item用appendChild添加到最低的那一列中。
//获取列的dom集合
const columns = document.querySelectorAll('.column');
//初始化最小列
let minHeightColumn = columns[0];
function waterfallLayout(item) {
for (let i = 0; i < columns.length; i++) {
if (columns[i].offsetHeight < minHeightColumn.offsetHeight) {
minHeightColumn = columns[i];
}
}
//添加进去
minHeightColumn.appendChild(item);
minHeightColumn = columns[0];
}
// 获取添加元素集合
const e = document.querySelectorAll('.item');
for (let i = 0; i < e.length; i++) {
waterfallLayout(e[i]);
}
元素方法,可以直接在html中运用。
- 思路三:直接用CSS中columns属性:
.wrapper {
/* 设置列数 */
columns: 3;
/* 设置间隔 */
column-gap: 10px;
}
最简便的方法,需要考虑一下样式之间是否相互影响。
总结
以上就是瀑布流实现的方式,具体实现方法我们可以自由选择,虽然css样式很简便,但用js手写的方法我们还是可以掌握下。