likes
comments
collection
share

大厂面试官:如何实现瀑布流? 带你从“-1”开始,码出瀑布。

作者站长头像
站长
· 阅读数 32

在我们浏览个个app时,会经常看见像这样类似的瀑布效果的图片布局方式,我们应该如何用js来实现呢?今天我们来谈谈同样是大厂面试官会谈到的话题--如何实现瀑布流

一、什么是瀑布流布局

大厂面试官:如何实现瀑布流?  带你从“-1”开始,码出瀑布。

1、像这样参差不齐的多栏布局,大多数的内容都是图片,并且图片的长度,宽度各不同,每张图片都紧密相连的充满屏幕,我们形象的称为瀑布流

2、优点:

  • 减缓用户的视觉疲劳
  • 增加页面的有效使用率

3、缺点:

  • 页面加载负担变大
  • 代码实现逻辑稍加复杂

二、具体代码实现

1、“伪代码的构想”--编程思路

当我们还没设置任何的样式,仅仅将图片放在页面中时,效果是这样的

大厂面试官:如何实现瀑布流?  带你从“-1”开始,码出瀑布。

(1)横向铺满 (2)纵向铺满

简单的两个代码思路就解决了瀑布流的实现。

2、代码的实现

给图片容器加上一些css属性,用float实现了让图片纵向铺满。

    *{
        margin: 0;
        padding: 0;
    }
    #container{
        position: relative;
    }
    .box{
        float: left;
        border: 1px solid #aaa;
    }
    .box-img{
        width: 188px;
        padding: 5px;
    }
    img{
        width: 100%;
    }
</style>

1、横向铺满

我们可以看到,当图片铺满第一行后,后面的图片似乎变得乱了起来。

大厂面试官:如何实现瀑布流?  带你从“-1”开始,码出瀑布。

这是因为float:left属性,将图片容器脱离文本流,当第一行放不下时,它会按照放下的最后一个元素的高度往前浮动,这时候前面已经放入的图片有更高的花,就会被挡住,展现出上图的布局效果。

这时候,我们就要解决第二步,将图片容器纵向铺满

2、如何解决纵向铺满呢?

“伪代码”--编程思路: 判断能第一列能放n张图片: 1、获取屏幕的宽度 2、获取图片的宽度,计算能放多少张图片

处理第n+1张之后的布局方法: 1、找第一列高度最低的图片 2、放置第n+1张后,更新该处图片的高度

3、具体代码

1、html代码
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    #container{
        position: relative;
    }
    .box{
        float: left;
        border: 1px solid #aaa;
    }
    .box-img{
        width: 188px;
        padding: 5px;
    }
    img{
        width: 100%;
    }
</style>
<body>
    <div id="container">
        <div class="box">
            <div class="box-img">
                <img src="./1.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./2.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./3.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./4.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./5.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./6.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./7.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./8.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./9.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./10.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./1.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./2.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./3.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./4.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./5.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./6.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./7.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./8.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./9.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./10.webp" alt="">
            </div>
        </div>
    </div>
    <script src="./index.js"></script>
</body>
</html>
2、JS代码
imgLocation('container', 'box')
function imgLocation(parent, child) {
  var cParent = document.getElementById(parent)
  var cChild = cParent.getElementsByClassName(child)
  var screenWidth = window.innerWidth
  cChild.onload = function(){
    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
      }
    }  
  }
}
3、最后瀑布效果

大厂面试官:如何实现瀑布流?  带你从“-1”开始,码出瀑布。

三、总结

拿到目标需求样式时,首要的并不是代码的实现,而是编程思路-“伪代码”的设计,这一步往往可以让你在接下来的代码编写中,达到事半功倍的效果。

转载自:https://juejin.cn/post/7369534132080656422
评论
请登录