面试官:你会怎么实现瀑布流布局 (附完整代码)

197 阅读2分钟

阿里最经典面试题:如何实现瀑布流

瀑布流是什么

首先,带大家了解一下瀑布流,大佬可以直接跳过。瀑布流就是对图片的排版,顾名思义,让图片像瀑布一样流下,打破了传统的一行归一行整齐划一的布局。这样说也许有些抽象,直接上图片吧。

掘金瀑布流.jpg 以本人京东主页面为例,这些购物链接就是采用的瀑布流布局,特点就是上下连接但左右并没有对齐,两列各排各的。

为什么要使用瀑布流,它受欢迎的地方在哪

这确实挺让人摸不着头脑的,整整齐齐的不挺好么。它的作用就在于引流,那么怎么用布局引流呢,人家都是用大数据打广告。我们将目光移到上面那张图片,可以发现,如果我想要看到那双耐克小白鞋的价格,我想要往下滑,而这样操作的同时,旁边的维他柠檬茶会显示出来,而这时,不管是好奇心要看看价格还是你确实想屯点柠檬茶,你都会接着往下滑,以此类推,你慢慢会发现你已经逛了很久,这就是瀑布流布局的套路,也是它受各大软件钟爱的原因。

怎么实现瀑布流

那么,现在我们进入正题,我们该怎么以最简单高效的方法去实现瀑布流呢?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./index.js"></script>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    #container{
      position: relative;
    }
    .box{
      float: left;
      padding: 5px;
    }
    .box-img{
      width: 150px;
      padding: 5px;
      border: 1px solid #aaa;
    }
    img{
      width: 100%;
    }
  </style>
</head>
<body>
  <div id="container">
    <div class="box">
      <div class="box-img">
        <img src="./img/pb1.jpg" alt="">
      </div>
    </div>
    <div class="box">
      <div class="box-img">
        <img src="./img/pb2.jpg" alt="">
      </div>
    </div>
    <div class="box">
      <div class="box-img">
        <img src="./img/pb3.jpg" alt="">
      </div>
    </div>
    <div class="box">
      <div class="box-img">
        <img src="./img/pb4.jpg" alt="">
      </div>
    </div>
    <div class="box">
      <div class="box-img">
        <img src="./img/pb5.jpg" alt="">
      </div>
    </div>
  </div>

  
</body>
</html>

现在请出我们的JS大佬

window.onload = function() {
    // 确定第一行能放几 n 张图
      // 1. 获取屏幕宽度
      // 2. 获取图片的宽度
    // 操作第 n+1 张 摆放它的位置  放在高度最小的那一列
      // 1. 获取每一列的高度
      // 2. 更新这一列的高度
  
    imgLocation('container', 'box')
  
    function imgLocation(parent, child) {
      var cParent = document.getElementById(parent)
      var cChild = cParent.getElementsByClassName(child)
      var screenWidth = window.innerWidth
      var imgWidth = cChild[0].offsetWidth
      var num = Math.floor(screenWidth / imgWidth)
      cParent.style.width = `${imgWidth * num}px`
  
      // 操作第 num+1 张
      var boxHeightArr = []
      for (var i = 0; i < cChild.length; i++) {
        if (i < num) {  // 第一行
          boxHeightArr.push(cChild[i].offsetHeight)
        } else {
          // 找数组最小值
          var minHeight = Math.min(...boxHeightArr)
          var minIndex = boxHeightArr.indexOf(minHeight)
  
          // 摆放图片
          cChild[i].style.position = 'absolute'
          cChild[i].style.top = minHeight + 'px'
          cChild[i].style.left = cChild[minIndex].offsetLeft + 'px'
  
          // 更新这一列的高度
          boxHeightArr[minIndex] = boxHeightArr[minIndex] + cChild[i].offsetHeight
        }
      }
    }
  }

效果图

image.png

结语

现在瀑布流布局运用相当广泛,在各种面试题中常常出现,大家在代码上有什么问题可以评论在下面。希望这篇文章可以对大家有帮助,也祝大家早日上岸。