用JS感受瀑布流布局的快感!

290 阅读3分钟

什么叫作瀑布流布局

首先得明白瀑布流布局的含义。
顾名思义,瀑布流又称瀑布流式布局,是一种多列等宽不等高的一种页面布局方式。视觉表现为参差不齐的多栏布局。这种展示方式可以使页面比较美观,让人有种错落有致的感觉。

image.png

如何实现瀑布流布局

像我们这样的代码萌新总是喜欢纠结代码该如何如何写,甚至去背代码!
代码实现的方法其实多种多样,我们更应该注重的是考虑如何实现业务功能。跟着自己的思路用语言把问题一步步剖解,接着再是自然而然地用代码实现。

1. 摆放第一行图片

因为设备不同,屏幕像素也就不同,所以我们合理地分析当前设备一行可以容纳多少张图片,也就是瀑布流的列数。

1.1 获取屏幕宽度以及图片宽度

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) //向下取整求得一列可容纳图片数

屏幕宽度除图片宽度可以得到瀑布流列数,这里应该用到向下取整。

2. 摆放剩下的图片

第一行以后的每张图片都应该考虑放到哪一列下面,因此需要得到每一列的高度,再将下一张图片放到最矮的那一列下。

2.1 找出最矮的一列

var boxHeightArr = [] //定义存放每一列高度的数组
var minHeight = Math.min(...boxHeightArr) //找数组最小值 也就是最矮的图片
var minIndex = boxHeightArr.indexOf(minHeight) //获取数组最小值的下标

2.2 将下一张图片放到最矮处

cChild[i].style.position = `absolute` //设置绝对定位
cChild[i].style.top = minHeight + `px` //设置定位位置
cChild[i].style.left = cChild[minIndex].offsetLeft + `px` //设置定位位置
boxHeightArr[minIndex] += cChild[i].offsetHeight  //更新这一列的高度

最后记住更新那一列的高度,以此循环往复。

HTML完整代码

<!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/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>

JS完整代码

//在window.onload中 js代码将在最后执行 这样script导入就可以放在任意位置
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
    // console.log(screenWidth);
    var imgWidth = cChild[0].offsetWidth
    // console.log(imgWidth)
    var num = Math.floor(screenWidth / imgWidth)//向下取整
    // console.log(num); // 8
    cParent.style.width = `${imgWidth * num}px`


    // 操作第 n+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)
            // console.log(minIndex);

            //摆放图片
            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);

}

代码萌新的个人见解,欢迎大佬纠错,一起加油吧!!