一起来看看阿里面试题-JS实现瀑布流布局(超详细版,附带解题思路和源码)>~<

什么是瀑布流布局?

在讲解之前我先来回答一下什么是瀑布流布局?
瀑布流布局(Waterfall Layout)是一种常见的网页和移动应用布局方式,特别是在展示图片、商品等内容的网站中。在瀑布流布局中,多个元素(如图片或文字区块)被排列成多列,每个元素的高度可以不同。当一列中加入了一个元素后,下一个元素会被放置到高度最低的那一列中,从而形成类似于瀑布向下流动的视觉效果。 下图为瀑布流布局的展示图。

瀑布流布局的实现核心

曾经有个老师教过我,程序实现的核心在于思维,其次才是代码。当你的思维正确时,写代码解决问题的速度自然不会慢,而且犯的错误更少代码也会更加有层次感和阅读性。那现在让我们分析一下瀑布流布局的解题思路和步骤

1. 确定一行可以放下多少张图片,也就确定了瀑布流布局的列数。

        1.1 获取屏幕宽度和图片的宽度来获取瀑布流布局的列数
        1.2 创建一个数组来存放并且更新瀑布流布局的每一列高度,数组初始值应当为第一行图片的高度

2. 在第一行图片放完之后,剩下的图片放入时应当检测瀑布流布局中所有列的最低高度然后绝对定位放入

         2.1 每次放入时,获取每一列的高度来找出最小高度列

         2.2 通过对图片进行绝对定位进行图片放置并且更新这一列的高度

瀑布流布局的代码实现

JavaScript部分

1  获取屏幕和图片盒子宽度来计算一行可以展示的图片(瀑布流的列数)
        let cParent =document.getElementById(parent);//获取容器元素        
        let cChild =cParent.getElementsByClassName(child); //获取所有图片元素
        let screenWidth =window.innerWidth;//获取浏览器自带宽度
        let imgWidth =cChild[0].offsetWidth;//获取图片元素的宽度
        let num =Math.floor(screenWidth/imgWidth);//通过浏览器宽度除以图片宽度再向下取整即可获得瀑布流布局列数

2  创建数组来存放瀑布流布局每一列的高度,剩下的图片放入时应当检测瀑布流布局中所有列的最低高度然后绝对定位放入

        for(let i=0;i<cchild.length;i++){ if(i<num){="" boxheightarr.push(cchild[i].offsetheight);="" 前num个元素的高度就为瀑布流布局的第一行高度="" }else="" {="" num个之后的元素则需要寻找高度最低的列然后绝对定位放入="" let="" minheight="Math.min(...boxHeightArr);//找出最小列的高度" 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]+="cChild[i].offsetHeight;//更新这一列的高度" =原高度+新图片的高度="" }="" <="" code>

完整代码

// 确定第一行能放几张图 n+1
// 1.获取屏幕宽度
// 2.获取图片的宽度

// 操作第 n+1 张 摆放位置 放在高度最小的那一列

// 1.获取每一列的高度

// 2.更改图片之后进行更新这一列的高度
imgLocation('container','box');
function imgLocation(parent,child) {
    let cParent =document.getElementById(parent);        
    let cChild =cParent.getElementsByClassName(child); 
    let screenWidth =window.innerWidth;
    let imgWidth =cChild[0].offsetWidth;
    let num =Math.floor(screenWidth/imgWidth);
    // cParent.style.width =`${imgWidth*num}px`;
    // console.log(cParent);
    // console.log(cChild);
    console.log(num);
    // console.log(screenWidth);
    var boxHeightArr =[];
    for(let i=0;i<cchild.length;i++){ if(i<num){="" boxheightarr.push(cchild[i].offsetheight);="" }else="" {="" let="" minheight="Math.min(...boxHeightArr);" 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]+="cChild[i].offsetHeight;" }="" console.log(boxheightarr);="" <="" code=""></cchild.length;i++){></code></pre><code>

HTML部分

完整代码

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>瀑布流布局</title>


<div id="container">
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/1.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/2.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/3.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/4.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/5.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/6.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/7.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/8.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/1.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/2.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/3.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/4.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/5.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/6.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/7.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/8.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/1.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/2.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/3.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/4.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/5.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/6.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/7.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            <img src="https://juejin.cn/img/8.jpg" alt="">
        </div>
    </div>
</div>
<script src="./index.js"></script>

CSS部分

完整代码
    
        *{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%;
        }
    

如果觉得喜欢的话,请点个赞吧。小白努力学习中ing,大家一起加油!>~<


这是一个从 https://juejin.cn/post/7368855076130488339 下的原始话题分离的讨论话题