瀑布流布局:让美的事物更加美

121 阅读4分钟

瀑布流布局如今应用广泛,像是淘宝、小红书、百度的图片排布等等,而要去实现一个简单的瀑布流图片摆放也很简单,让我们直接进入正题

** 首先**

让我们先思考一下怎么去实现它,作为一个程序员,理好自己的思绪很重要

先,我们可以先摆好第一排,确定它可以放几张图片,然后将后续的图片一个一个插入第一排中高度最低的图片下
中,怎么摆好第一排,怎么确定它可以放几张图片,怎么将图片插入到高度最低的图片下
第一排我们可以直接利用浮动将第一排确定
第一排可以放的图片数量,我们可以先获取屏幕宽度及图片宽度,然后就可以相除取整获取数量
将图片插入到高度最低的图片下这一步,我们可以先获取每一列的高度,找出最小的列,然后插入即可

** 然后**

让我们了解一下需要用到哪些方法

1)css部分:
float:left

这个设置的作用是让所有元素按从左到右排列,并使其脱离文档流(元素不再按照文档流的排列方式进行布局,而是根据其他方式进行定位,使其不受浏览器底层逻辑的控制)

offsetWidth

用于获取元素的实际宽度,包括内边距、边框和滚动条(如果有),但不包括外边距。它的值是一个整数,以像素为单位。

offsetHeight

用于获取元素的像素高度,高度包含该元素的垂直内边距和边框,且是一个整数,不包含外边距。

offsetLeft

用于获取元素相对于其offsetParent元素的左侧位置的像素值。offsetParent元素是最近的已定位的祖先元素,如果没有已定位的祖先元素,那么offsetParent元素就是body元素。

2)js部分
document.getElementById()

是 JavaScript 中用于通过元素的 ID 来获取特定元素的方法

getElementsByClassName()

用于返回文档中所有具有指定类名的元素组成的集合(类数组对象)

window.innerWidth 

表示当前浏览器窗口的内部宽度(不包括滚动条等的宽度),以像素为单位。

Math.floor

向下取整(去小数)

Math.min(...Arr)

取得数组中的最小值

** 最后**

用代码去实现它

html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #container{
            position: relative;
        }
        .box{
            float: left;
            padding: 5px;
        }
        .box-img{
            width: 150px;
            padding: 5px;
        }
        img{
            width: 100%;
        }
    </style>
    
</head>
<body>
    <script src="./index.js"></script>
    <div id="container">
        <div class="box">
            <div class="box-img">
                <img src="./img/1.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/2.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/3.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/4.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/5.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/6.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/7.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/8.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/9.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/10.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/1.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/2.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/3.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/4.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/5.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/6.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/7.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/8.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/9.webp" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/10.webp" alt="">
            </div>
        </div>
        
    </div>

    
</body>
</html>

在代码中我们先是存入了三种容器,一个是“container”容器用于存放“box”容器方便操作,一个是“box”容器用于存放图片容器,一个是图片容器用于对图片进行设置,然后对容器进行了一些设置 其中较为重要的有posation、float及width:100%这三条,分别是方便使用弹性定位、设置第一排及图片不变形的作用。最后引入js文件。

Javascript

    // 确定第一行能放几 n 张图
       //1.获取屏幕宽度
       //2.获取图片宽度
    // 操作第 n+1 张摆放他的位置 放在高度最小的那一列
       //1.获取每一列的高度
       //2.update这一列的高度
    imgLocation('container','box')

    function imgLocation(parent,child){
        //确定第一行能放num张图
        var cParent=document.getElementById(parent)
        var cChild=cParent.getElementsByClassName(child)
        var screenWidth = window.innerWidth
        var imgWidth = cC[0].offsetWidth
        var num =   (screenWidth/imgWidth)
        cParent.style.width = `${imgWidth * num}px`


        // 操作第num+1张
        var boxHeightArr = []
        for(var i=0; i<cC.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'
                
                // update 这一列的高度
                boxHeightArr[minIndex] = boxHeightArr[minIndex] + cC[i].offsetHeight
            }
        
        }
        
    }
}

在这些代码中,利用了一个function来实现功能,先通过screenWidth获取屏幕宽度、imgWidth获取图片宽度得出num,并固定cparent这个容器的宽度,然后通过一个for循环,通过num将第一排的高度固定为一个数组,找出其中的最小值后,将后续的图片设置为Absolute(以container为定位,做弹性,并使其脱离文档流),获取最小值的offsetLeft来作为后续图片的距屏幕左边的宽度,以高度最小值作为Top来对后续图片进行定位,最后更新这一列的高度并存进数组。循环开始直到遍历完所有的图片,最后,一个瀑布流布局就完成了。下面是效果图:

image.png

** 小结**

这是一个比较简单的瀑布流布局实现过程,遗憾的是不能随着浏览器的屏幕更新而更新布局,如有其他不足,欢迎指正。

最后的最后,谢谢观看!