ES6+JQuery实现瀑布流效果

本文详细介绍了如何使用JavaScript和jQuery实现瀑布流布局,包括计算列数、排列图片、处理高度、响应式调整及懒加载事件。代码示例展示了如何动态加载图片并随着窗口大小变化调整布局,实现流畅的图片展示效果。
摘要由CSDN通过智能技术生成

瀑布流

1. 定位后确定浏览器显示区域内,一行能放多少列图片盒子。

  1. 获取页面的宽度获取图片盒子的宽度

  2. 获取页面的宽度获取图片盒子的宽度

  3. 显示的列数=页面宽度/图片盒子宽度

  4. column = pageWidth / itemWidth

2. 确定列数之后,排列第一行

  • 下面还有很多图片盒子,我们先要排列第1行,所以在for循环里就要判断一下,当i(所有图片盒子的索引)<column(显示列数)的时候,说明在第1行;

  • 知道在第1行之后,动态设置每个图片盒子的left值就能排好第1行。

  • left = i * ( itemWidth + gap );

3. 第1行排列好之后,获取第1行所有图片盒子的高度

  • 需要定义一个数组arr,将获取到的高度存在数组中,因为第2行排列的时候需要考虑top值,此时只能根据第1行图片盒子的高度来设置;
    获取图片高度的时候要注意,程序必须写在入口函数onload里面,因为图片的加载特性是︰等页面都加载完之后才去请求加载,所以不写在入口函数里可能会出现高度获取不到的情况。

4. 排列第二行

  • 获取到刚刚数组中,高度最小的那一列,将第2行的第1个图片盒子放置在它的下方;
  • 此时的left值就是高度最小列的offsetLeft;top值就是∶第1行高度最小列的高度(为了布局美观可以加上上下间隙gap)。
  • 记录下高度最小列的索引index,后面计算会用到;
  • 设置完成之后,会发现后面所有的图片都叠在这个高度最小列的下面,原因就是此时的最小列高度没有改变,应该加上下面图片的高度,得出一个新高度。

5. 改变最小列当前高度

  • 此时的这一列高度其实已经发生改变了,所以需要将新高度赋值给数组

  • 当前高度最小列的高度=当前高度最小列的高度+间隙+下面图片盒子的高度

6. 触发resize事件

  • 将整个设置样式的部分封装成一个函数,在onload里面注册一个resize事件,只要页面一发生改变,就触发样式部分的代码。

  • 实时改变pageWidth的宽度,这样瀑布流就会是一个响应式的效果了

7. 懒加载事件

  • 通过页面可视区高度+滚动条卷去的高度 = 最后一张图片图片的offsetTop的时候加载下面的图片

8. 代码示例:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>瀑布流</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            position: relative;
        }

        img {
            width: 220px;
            display: block;
        }

        .item {
            box-shadow: 2px 2px 2px #999;
            position: absolute;
        }
    </style>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<!-- html 部分 -->
<div id="box">
    <!--<div class="item"><img src="../image/瀑布流/001.jpg" alt=""></div>
    <div class="item"><img src="../image/瀑布流/030.jpg" alt=""></div>-->
</div>

<script>
    let imgList = [
        "https://s5.mogucdn.com/mlcdn/c45406/210123_80fb475jaa3c85a2b533ake67c5jb_5000x6660.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/55cf19/201007_5ef1begkc3k33254fca8kcjk26703_640x960.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210504_2bgkjaekcgl7al11fllk576k19g2d_6157x9236.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/201005_3747744121i53l20gl7e5df72f101_4999x7499.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210713_19h2fa2ff2i7leb0iib0h1hacbc0f_750x750.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/200911_60age6f2k4ekic0ii8j550699a394_715x751.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210803_3eekh543e8ak9k1j4g4c8l0h74gd7_800x1200.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/55cf19/210401_2ihd8726caji6llkjf9j5fhjja49c_640x960.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210806_8c362g6jeab3i660l4e4fidbe4fd4_1080x1440.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/55cf19/210511_3245e1i1569k16396h8k6d26gehh8_640x960.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210306_69ilei699h450bd84cb4cha9b31jj_5732x8599.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/55cf19/210421_602kie0e85e16ie38fd7jab9g488j_750x1000.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210522_34igd3eabfal5e9i4cdlch3i2767k_640x960.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/55cf19/210122_1ge4g5l19jij5af218c6h9ig9abh7_640x960.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/201007_754i59abjh334k7ccd1klifc82hjj_4464x5999.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210319_2ck168b51342db5k6772ljhf7lgl4_3800x5000.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/200501_1iacl56kkel7e98flhg8h510gkdhb_640x961.jpg_500x9999.v1c7E.81.webp",
        "https://s5.mogucdn.com/mlcdn/c45406/210710_07bbcac5443i981l5alh45ilab6a4_640x960.jpg_500x9999.v1c7E.81.webp"
    ]

    //创建图片元素
    for (let i = 0; i < imgList.length; i++) {
        let img = $(` <div class="item"><img src=${imgList[i]} alt=""></div>`)
        $("#box").append(img)
    }

    // 定义每一列之间的间隙 为10像素
    const gap = 10;

    window.onload = function () {

        waterfall()

        function waterfall() {
            const items = $("#box").children()
            const pageWidth = getClient().width;
            const itemWidth = items[0].offsetWidth;
            // 1- 确定列数  = 页面的宽度 / 图片的宽度
            const columns = parseInt(pageWidth / (itemWidth + gap));
            const arr = [];
            $.each(items, (index, element) => {
                if (index < columns) {
                    $(element).css({
                        top: 0,
                        left: (itemWidth + gap) * index
                    })
                    arr.push(element.offsetHeight)
                } else {
                    //其他行
                    // 3- 找到数组中最小高度  和 它的索引
                    let minHeight = arr[0];
                    let minIndex = 0;
                    for (let j = 0; j < arr.length; j++) {
                        if (minHeight > arr[j]) {
                            minHeight = arr[j];
                            minIndex = j;
                        }
                    }
                    // 4- 设置下一行的第一个盒子位置
                    // top值就是最小列的高度 + gap
                    $(element).css({
                        top: arr[minIndex] + gap,
                        left: items[minIndex].offsetLeft
                    })
                    // 5- 修改最小列的高度
                    // 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
                    arr[minIndex] = arr[minIndex] + items[index].offsetHeight + gap;
                }
            })
        }

        window.onresize = () => {
            waterfall()
        }

        //当加载到最后一张的时候,加载更多图片
        window.onscroll = () => {
            const items = $("#box").children()
            if (getClient().height + getScrollTop() >= items[items.length - 1].offsetTop) {
                console.log("aaa")
                //模拟从后台请求的数据
                const data = [
                    "https://s5.mogucdn.com/mlcdn/c45406/210123_80fb475jaa3c85a2b533ake67c5jb_5000x6660.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/55cf19/201007_5ef1begkc3k33254fca8kcjk26703_640x960.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210504_2bgkjaekcgl7al11fllk576k19g2d_6157x9236.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/201005_3747744121i53l20gl7e5df72f101_4999x7499.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210713_19h2fa2ff2i7leb0iib0h1hacbc0f_750x750.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/200911_60age6f2k4ekic0ii8j550699a394_715x751.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210803_3eekh543e8ak9k1j4g4c8l0h74gd7_800x1200.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/55cf19/210401_2ihd8726caji6llkjf9j5fhjja49c_640x960.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210806_8c362g6jeab3i660l4e4fidbe4fd4_1080x1440.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/55cf19/210511_3245e1i1569k16396h8k6d26gehh8_640x960.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210306_69ilei699h450bd84cb4cha9b31jj_5732x8599.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/55cf19/210421_602kie0e85e16ie38fd7jab9g488j_750x1000.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210522_34igd3eabfal5e9i4cdlch3i2767k_640x960.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/55cf19/210122_1ge4g5l19jij5af218c6h9ig9abh7_640x960.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/201007_754i59abjh334k7ccd1klifc82hjj_4464x5999.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210319_2ck168b51342db5k6772ljhf7lgl4_3800x5000.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/200501_1iacl56kkel7e98flhg8h510gkdhb_640x961.jpg_500x9999.v1c7E.81.webp",
                    "https://s5.mogucdn.com/mlcdn/c45406/210710_07bbcac5443i981l5alh45ilab6a4_640x960.jpg_500x9999.v1c7E.81.webp"
                ]
                for (let i = 0; i < data.length; i++) {
                    let element = $(`<div class="item"><img src=${data[i]} alt=""></div>`)
                    $("#box").append(element)
                }
                waterfall()
            }
        }
    }


    //兼容性处理
    function getClient() {
        return {
            width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
            height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
        }
    }

    function getScrollTop() {
        return window.pageYOffset || document.documentElement.scrollTop;
    }
</script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值