我的第一篇博客 —— 用 js 和 css 简单实现瀑布流布局

sdbxpjzq 2020-04-07

一个拖延症晚期患者的自述:

注册了博客快一个月了,终于要迎来我的第一篇博客了哈哈哈!!!

刚注册的时候,满脑子要频繁更新,扩充自己的知识库,一到真正落实,就不得不为懒惰屈服,还好有了学习计划,以后应该会每周一更(不更当我没说)。当然了,肯定是希望被更多人看到,帮助到大家,如果没人看的话就当作是自己的积累与记录吧!

还有,我目前工作是前端工程师,还是一名刚入行不久的菜鸟哈哈哈!!!现在主要目标是先把前端知识巩固好,再逐步往全栈领域发展(毕竟装13是我一生的职责)。

所以,请各位大佬们多多指教,如果看到小弟哪里写的不好或有问题,烦请多多指出,可在评论区尽情 diss 我,我保证不还嘴哈哈哈!!!

那么,以下就隆重迎来我的第一篇博客(正经脸.jpg)。


 前段时间在工作中遇到的一个之前没做过的需求,可能对其他人来说是再简单不过的吧。但小弟愚笨,找了挺多方法最终决定用这个方法来实现需求,没错,就是实现瀑布流布局,在这里我用的是 js 和 css 来实现。

如果有一个数组为 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15](数组元素这里简单用下标代替)来实现瀑布流,并且不打乱原本的数组顺序。

这篇文章的解决思路是可以把数组重新组合成 [ [0, 4, 8, 12], [1, 5, 9,13], [2, 6, 10, 14], [3, 7, 11, 15] ] 这样的一个二维数组,然后将每一个小数组垂直排序。这样的话无论每一个数组元素高度多高,都能实现紧密的排序,并且不打乱原本的顺序,也就是瀑布流布局。

主要难点在于如何兼容不确定列,现在是四列,如果我想五列呢?所以我们应该写一个能够兼容我们需求的拆分数组的方法。

在这里,我们可以通过 reduce() 写一个方法实现拆分数组:

// 子元素下标除以列数的余数 = 子元素所在列的下标// data 为你想要拆分的数组,column 为拆分的列数splitData (data, column) {
  return data.reduce((total, currentValue, currentIndex) => {
    const columnIndex = currentIndex % column
    if (total[columnIndex] === undefined) {
      total[columnIndex] = []
    }
    total[columnIndex].push(currentValue)

    return total
  }, [])
}

接下来就是调用此方法,实现拆分数组,并渲染出页面,在这里是用 vue 实现:

<div class="wrap">
  <div v-for="(listItem, listIndex) in list" :key="listIndex" class="waterfall">
    <div v-for="(item, index) in listItem" :key="index" class="item">
      <div class="content">{{ item.index }}:{{ item.val }}</div>
    </div>
  </div>
</div>

最后需要通过 css 将每一个二维数组中的子数组垂直排序,这里我们可以用 flex:

.wrap {
  display: flex;
  flex-direction: row;

  .waterfall {
    width: 25%; // 宽度由列数决定,这里是4列所以为25%
    display: flex;
    flex-direction: column;
    padding: 0 5px;

    .item {
      margin-bottom: 10px;
      box-sizing: border-box;
      break-inside: avoid;

      .content {
        padding: 10px;
        font-size: 20px;
        color: #686868;
        box-sizing: border-box;
        border: 1px solid #ccc;
      }
    }
  }
}

实现的效果:

我的第一篇博客 —— 用 js 和 css 简单实现瀑布流布局

这样我们就愉快的实现瀑布流啦!当然,这可能只能满足一部分需求,如果有大佬有更好的方法欢迎在评论区留言分享!!!

相关推荐