原生JavaScript实现瀑布流布局插件详解

作者:函数茶馆时间:2026-10-24 16:38:50浏览:411

本文详细介绍如何使用原生JavaScript制作瀑布流布局插件。通过传入容器、图片数组及宽度参数,自动计算列数与间隙,利用绝对定位动态分配图片坐标。核心算法基于寻找最短列进行排列,并包含窗口resize时的重排逻辑,适合需要无依赖实现图片网格展示的前端场景。

本文分享了一个使用原生JavaScript编写的瀑布流插件的具体实现代码,供开发者参考。

该插件的使用方式与常规瀑布流一致,调用时仅需传入容器元素、图片列表以及单张图片的宽度,即可自动生成瀑布流效果。

接下来直接展示代码实现,随后将解析其核心思路。

HTML结构与CSS样式配置

首先介绍HTML结构及插件调用方式,HTML部分仅需一行基础代码。


<body>
    <div class="main"></div>
 
    <script src="index.js"></script>
    <script>
        // 第一个参数,瀑布流容器
        var dom = document.getElementsByClassName("main")[0];
        // 第二个参数,图片链接,写入一个数组
        var imgArr = ["img/0.jpg","img/45.jpg","img/225.jpg","img/3.png","img/7729.png","img/a.jpg","img/ama.jpg","img/c.png","img/0.jpg","img/3.png","img/45.jpg","img/225.jpg","img/7729.png","img/a.jpg","img/ama.jpg","img/c.png",];
        // 调用插件,传入参数,第三个是图片宽度
        waterFallFlow(dom,imgArr,220);
    </script>
</body>

接着展示与HTML对应的CSS样式代码。

其中,.main为传入的容器元素,必须设置position: relative;以确保内部绝对定位的图片能正确参照该容器定位。

此外,.main img{transition: all 0.5s;}用于为容器内所有图片添加过渡动画效果。


.main{
    border: 1px solid #ccc;
    width: 90%;
    margin: 0 auto;
    position: relative;
}
.main img{
    transition: all 0.5s;
}

JavaScript插件核心代码

以下是核心的JavaScript代码部分。


/**
 * @param {*} dom 代表瀑布流容器
 * @param {*} imgArr 图片数组
 * @param {*} wid 图片宽度
 */
function waterFallFlow(dom, imgArr, wid) {
    var gap;//间隙
    var colNumber;//列数
    imgDom();
    setImgPos();
    //窗口发生改变的时候
    window.onresize = function(){
        setImgPos();
    }
    /**var timer = null;
     * 上面这么写,丝滑,但是过于影响性能,拖动窗口时
     * 非常非常频繁的调用函数对图片进行重新拍排布
     * 
     * 可以这样,防抖
     * 
     * window.onresize = function(){
     * if(timer){
     *  clearIntval(timer);
     * }
     *  timer = setTimeout(function(){
     *  setImgPos();
     * },300);
     * }
     * 
     */
    // 生成DOM元素
    function imgDom() {
        for (let i = 0; i < imgArr.length; i++) {
            const url = imgArr[i];
            let img = document.createElement("img");
            img.src = url;
            img.style.width = wid + "px";
            img.style.position = "absolute";
            // 所有图片使用绝对定位
            img.style.left = "";
            img.style.top = "";
            img.onload = function(){
                setImgPos();//图片的异步加载
            }
            dom.appendChild(img);
        }
    }
    // 设置每张图片的坐标
    function setImgPos() {
        cal();
        var colY = new Array(colNumber);//存放每一列下一个图片的Y坐标
        colY.fill(0);//填充数组为0
        for (let i = 0; i < dom.children.length; i++) {
            var imgM = dom.children[i];
            var y = Math.min(...colY);//求最小值
            var index = colY.indexOf(y);//第几列
            var x = (index + 1) * gap + index * wid;
            imgM.style.left = x + "px";
            imgM.style.top = y + "px";
            //更新数组
            colY[index] += parseInt(imgM.height)+gap;
        }
        //找到数组中最大的数字,来解决父级div塌陷问题
        var h = Math.max(...colY);
        console.log(h);
        dom.style.height = h + "px";
    }
    // 计算相关数据
    function cal() {
        var containerWidth = parseInt(dom.clientWidth);
        colNumber = Math.floor(containerWidth / wid);//列数
        var space = containerWidth - colNumber * wid;
        gap = space / (colNumber + 1);//计算间隙
 
    }
}

代码中已添加详细注释,便于理解各部分功能。

瀑布流布局算法思路

下面详细解析实现思路。

第一步是接收传入的参数,包括容器元素、图片数组以及图片设定的宽度。

第二步是创建图片DOM元素,并将其添加到指定的容器中。

第三步是为每张图片设置宽度,高度保持自适应,同时计算列数和图片之间的间距。

第四步是利用绝对定位对图片进行排布,计算每张图片对应的left和top值,即x和y坐标。

前三步逻辑较为直观,重点在于第四步的具体实现。

核心思想如下:

HTML结构与CSS样式配置

主要策略是始终寻找当前高度最短的一列,将下一张图片排列在该列,图中示例显示最短列位于第二列。

HTML结构与CSS样式配置

当图片添加到当前最短列后,继续寻找新的最短列,并将后续图片依次添加,如此循环。

HTML结构与CSS样式配置

通过上述逻辑完成整个瀑布流的排布,具体执行过程如下。

首先计算页面能容纳的图片列数,创建一个长度等于列数的数组,初始值全部填充为0,用于后续存储各列的y坐标(高度)。

HTML结构与CSS样式配置

遍历容器内的子元素,在循环中找出数组中的最小值及其索引(即列号),该索引即为当前图片的y坐标。

HTML结构与CSS样式配置

确定y坐标后,接下来计算x坐标。

x坐标的计算公式为:x = (列数 + 1) * 间距 + 当前列号 * 图片宽度(传入的参数)。

通过上述计算即可确定图片的具体位置。

HTML结构与CSS样式配置

需要注意的是,每次添加图片后必须更新数组,即修改已添加图片所在列的y坐标,同时需处理图片的异步加载情况。

以上即为本文的全部内容,希望对学习有所帮助,欢迎支持本站。

作者最新文章