需求小能手——瀑布流

805 阅读2分钟

前言

前端有很多经典的布局,比如圣杯布局、弹性布局、多栏布局等,这几个布局相对而言比较简单,本节介绍的瀑布流布局也是一种经典布局,它的实现要复杂一点,如果你还不能手写一个瀑布流,那就一起来学习下。

瀑布流

含义

瀑布流布局的特点就是元素高度不一样,每一行元素有高有低,凸显出凌乱美,不像弹性布局那种规规矩矩的。这种布局适用于图片或内容的展示,比如:

35(~AVO1EPN45KF5ER)Q196.png

实现

瀑布流看起来很乱,但它还是遵循着自己的规律,每次元素会插入到高度最低的一列,这是瀑布流核心思想,所以上述图例中元素插入顺序应该是:

image.png 这种方式能够有效的利用空间,瀑布流也相当于是性能优化的一种方式。要想实现瀑布流就抓住核心思路就行,具体方法也有好几种:

  • 思路一:假设容器宽度等分为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手写的方法我们还是可以掌握下。