js实现瀑布流

news2025/7/14 15:30:20

我们浏览网站的时候尤其是图片网站,我们会发现大大小小的图片,紧密的排列在一起,就像瀑布一样看着非常舒服,虽然css可以通过cloums来指定,
像我们这次的图片项目用的就是css实现的,最后布局是用grid布局写的,最后比较懒,就没有改成js实现的瀑布流,因为其比较耗性能而且每次都会重排,用户体验不好,所以更多的还是用js去写,这里就来分享一下吧。


核心js代码

//第一个值是父元素,第二个是子元素,第三个是指定多少列
function waterFall(parentEle, childEle, cols) {
    //根据图片的列数来确定父盒子的宽度,父盒子居中
    //获取标签,父盒子和所有子盒子
    var father = document.getElementById(parentEle)
    var allBox = document.getElementsByClassName(childEle)
    //获取其中一个的宽度
    var boxWidth = allBox[0].offsetWidth
    //获取文档的宽度(兼容)
    var screen = document.documentElement.clientWidth || document.body.clientWidth
    // 父盒子居中,给父盒子设置宽度
    father.style.width = cols * boxWidth + 'px'
    father.style.margin = '0 auto'
    //子盒子定位(从第二行开始)
    // 定义变量
    var heightArr = [], boxHeight = 0, minBoxHeight = 0, minIndex = 0
    //遍历所有的盒子
    for (let i = 0; i < allBox.length; i++) {
        boxHeight = allBox[i].offsetHeight
        //判断是否是第一行
        if (i < cols) {
            heightArr.push(boxHeight)
        } else { //剩余行做定位
            //取出数组中最矮盒子的高度
            minBoxHeight = heightArr[minBox(heightArr)]
            //取出最矮盒子再数组中的索引
            minIndex = minBox(heightArr)
            //剩余子盒子的定位
            allBox[i].style.position = 'absolute'
            allBox[i].style.left = minIndex * boxWidth + 'px'
            allBox[i].style.top = minBoxHeight + 'px'
            /*
            更新高度(利用更新这个数组实现动态找最低的
            每次循环时会在原本最低的那个盒子的高度基础上加上新添加的盒子的高度)
            */
            heightArr[minIndex] += boxHeight
        }
    }
}
// 获取高度最小的一个值
function minBox(box) {
    var j = 0
    for (i in box) {
        if (box[j] > box[i]){
            j = i
        }
    }
    return j
}

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>瀑布流</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            border: none;
        }

        img {
            width: 200px;
            vertical-align: top;
        }

        #main {
            position: relative;
        }

        .box {
            float: left;
            padding: 15px 0 0 15px;
        }

        .pic {
            padding: 10px;
            border: 1px solid #ccc;
        }

        .clearFloat::after {
            content: "";
            display: block;
            clear: both;
        }
    </style>
</head>

<body>
    <button onclick="sureFn()">确定</button>
    <div id="main" class="clearFloat">
        <div class="box">
            <div class="pic">
                <img src="./img/huidilogo.png" alt="">
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./img/613927.jpg" alt="">
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <div class="" style="display: grid;">
                    <img src="./img/677283.jpg" alt="">
                    <span>123</span>
                </div>
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./img/680381.png" alt="">
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./img/911401.jpg" alt="">
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./img/huidilogo.png" alt="">
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./img/huidilogo.png" alt="">
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./img/613927.jpg" alt="">
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <div class="" style="display: grid;">
                    <img src="./img/677283.jpg" alt="">
                    <span>123</span>
                </div>
            </div>
        </div>
    </div>
    <script>
        window.addEventListener("load", function () {
            waterFall('main', 'box', 4);
        });
        //2、加载数据(追加)
        function sureFn() {
                let str = `
            <div class="pic">
                <img src="./img/1.png" alt="">
            </div>
                `
                var newBox = document.createElement('div');
                newBox.className = 'box';
                newBox.innerHTML = str
                document.getElementById('main').appendChild(newBox);
                //重新进行瀑布流布局
                waterFall('main', 'box', 4);
            }
        }
        function waterFall(parentEle, childEle, cols) {
            var father = document.getElementById(parentEle);
            var allBox = document.getElementsByClassName(childEle);
            var boxWidth = allBox[0].offsetWidth;
            var screen = document.documentElement.clientWidth || document.body.clientWidth;
            father.style.width = cols * boxWidth + 'px';
            father.style.margin = '0 auto';
            var heightArr = [], boxHeight = 0, minBoxHeight = 0, minIndex = 0;
            for (let i = 0; i < allBox.length; i++) {
                boxHeight = allBox[i].offsetHeight;
                if (i < cols) {
                    heightArr.push(boxHeight)
                } else { 
                    minBoxHeight = heightArr[minBox(heightArr)];
                    minIndex = minBox(heightArr);
                    allBox[i].style.position = 'absolute';
                    allBox[i].style.left = minIndex * boxWidth + 'px';
                    allBox[i].style.top = minBoxHeight + 'px';
                    heightArr[minIndex] += boxHeight;
                }
            }
        }
        function minBox(box) {
            var j = 0;
            for (i in box) {
                if (box[j] > box[i])
                    j = i
            }
            return j;
        }
    </script>

</body>

</html>

效果图
在这里插入图片描述
总结
之后再写项目的话,不能像这次项目那样用最简单的方式去实现瀑布流,要想到用户体验和一些性能的考虑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17903.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring(一)】如何获取对象(Bean)

目录 一、前言 二、Spring的下载 三、快速入门 四、IOC&#xff08;控制反转&#xff09; 五、创建XML配置文件 六、获取Bean   1. 按类型来获取Bean   2. 按id来获取Bean   3. 按idclass来获取Bean   4. 默认的一种特殊方式获取Bean   5. 有关id的一些说明 相关文章 Serv…

cpu设计和实现(流水线上的第一条指令)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 读书的时候&#xff0c;《计算机组成原理》也看了&#xff0c;《计算机体系结构》也学了&#xff0c;老师也给我们讲了各种各样的流水线知识&#…

Spring框架笔记

Spring51. 什么是Spring框架1.1 spring的特点2. IOC2.1 什么是IOC2.2. 基于xml的IOC2.2.1 创建对象2.2.2 给创建的对象赋值2.2.2.1 使用setter方法注入2.2.2.2 使用构造方法注入2.3 基于注解IOC2.3.1 创建对象的注解2.3.2 依赖注入的注解2.3.3 添加包扫描2.3.3.1 添加包扫描多种…

小目标检测:基于切图检测的yolov5小目标训练

目前在目标检测方面有着众多的检测框架&#xff0c;比如两阶段的FasterRcnn、以及yolo系列的众多模型。yolo系列在实际中用的最多&#xff0c;一方面性能确实不错&#xff0c;另一方面具有着较多的改进型系列。今天我们主要使用的yolov5系列。具体原理过程就不多说了&#xff0…

数字化助力生产制造管理:家具行业管理系统

中国家具产业经过近 40 年的发展&#xff0c;占到世界家具生产 1 /4 强&#xff0c;是全球生产和出口第一大国&#xff0c;在世界上有着广泛的影响和关注。中国家具产业也是国民经济的重要支柱产业&#xff0c;2018 年总产值达到16 000 亿元&#xff0c;占中国 GDP 2%多。 然而…

数据库高级 IV

数据库高级 IV 二分查找算法 定义 二分查找也称折半查找&#xff08;Binary Search&#xff09;&#xff0c;它是一种效率较高的查找方法。但是&#xff0c;折半查找要求线性表必须采用顺序存储结构&#xff0c;而且表中元素按关键字有序排列前提要求:1. 线性表必须采用顺序存…

[附源码]计算机毕业设计JAVA火车票预订系统2022

[附源码]计算机毕业设计JAVA火车票预订系统2022 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybat…

[附源码]SSM计算机毕业设计智能超市导购系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

STM32所有系列keil 开发包的下载链接 - Keil.STM32Fxxx_DFP.x.x.x.pack

文章目录1、官网下载链接及操作步骤2、关于Keil官网下载芯片包的网速很慢的解决办法1、官网下载链接及操作步骤 安装Keil之后&#xff0c;需要安装芯片包&#xff0c;但是在软件上面点击下载安装&#xff0c;会非常慢。还不如自己到官网下载的快。 官网下载地址&#xff1a;…

longjmp导致局部变量丢失

0 总结 longjmp与setjmp语句之间的变量赋值会丢失。变量须满足&#xff1a; 在调用setjmp函数中的局部变量&#xff08;栈变量&#xff09; &#xff0c;全局变量不受影响非volatile 解决方法&#xff1a;加volatile 1 问题复现 #include <setjmp.h> #include <s…

H5的基础

网页的学名称作HTML文件&#xff0c;是一种可以在www网上传输&#xff0c;并被浏览器认识和翻译成页面显示出来的文件。 HTML是&#xff1a;Hypertext Marked Language即超文本标记语言&#xff0c;是一种用来制作超文本文档的简单标记语言 超文本就是指页面内可以包含图片&…

六十分之九十——沉迷期的突破

目录一、目标二、计划三、完成情况四、提升改进(最少3点)五、意外之喜(最少2点)六、总结一、目标 明确可落地&#xff0c;对于自身执行完成需要一定的努力才可以完成的 1.8本技术管理书籍阅读(使用番茄、快速阅读、最后输出思维导图)2.得到"逻辑思维"、吴军硅谷来信…

WebRTC GCC 拥塞控制算法(REMB-GCC)

目录 一. 前言 二. REMB-GCC算法原理 1. 接收端基于延时梯度的带宽预估 &#xff08;1&#xff09;Arrival-time filter &#xff08;2&#xff09;Overuse Detector &#xff08;3&#xff09;Adaptive threshold &#xff08;4&#xff09;Remote Rate Controller &a…

【SQL】之索引

【SQL】之索引简单的索引设计方式innodb中的索引设计方式迭代一次迭代两次迭代三次btree聚簇索引二级索引&#xff08;非聚簇&#xff09;联合索引&#xff08;非聚簇&#xff09;InnoDB的B树索引的注意事项myISAM中索引设计方案索引是帮助mysql高效获取数据的数据结构简单的索…

查询

一、顺序查询 普通查找方式&#xff1a; int SeqSearch(int a[],int n,int k) {int i 0;while (i < n && a[i] ! k)i;if (i > n)return 0;elsereturn i 1; } 优化版查找方式&#xff1a; int OPSeqSearch(int a[], int n, int k) {int i 0;a[n] k;while …

全志A33使用主线U-Boot方法

最近在研究A33主线相关的资源&#xff0c;目前主线uboot和内核都对A33有极好的支持了&#xff0c;所以现在把我在使用过程中遇到的问题和使用方法做个记录&#xff0c;首先是下载主线uboot源码&#xff0c;网址为https://ftp.denx.de/pub/u-boot/&#xff0c;我下载的版本为202…

点云 ICP学习-IterativeClosestPoint

目录 一、pcl中 点云配准算法 二、关于svd原理求解部分 三、pcl IterativeClosestPoint 完成demo 一、pcl中 点云配准算法 PCL 库中 ICP 的接口及其变种&#xff1a; 点到点&#xff1a;pcl::IterativeClosestPoint< PointSource, PointTarget, Scalar >点到面&…

RocketMQ——Mac电脑OS系统docker安装Dashboard

文章目录引言安装下载dashboard镜像docker pull镜像查看镜像运行容器启动容器查看容器日志问题解决方案解决方案说明登录dashboard界面关注微信公众号&#xff1a;CodingTechWork&#xff0c;一起学习进步。引言 前面的文章已经介绍过如何在OS系统上安装并启动使用RocketMQ&…

Canal 安装与入门

MySQL Binlog 简介 https://blog.csdn.net/weixin_44371237/article/details/127904514 MySQL 主从复制过程 1&#xff09;Master 主库将改变记录&#xff0c;写到二进制日志(Binary Log)中&#xff1b; 2&#xff09;Slave 从库向 MySQL Master 发送 dump 协议&#xff0c…

基于QT的考试管理系统设计与实现

目录 一、项目概要 4 1.1项目名称 4 1.2项目目标 4 1.3软件概要 4 1.4功能描述 5 1.5开发环境 5 1.6关键技术 6 1.7开发体制 6 1.8开发阶段 6 二、软件详细需求 7 2.1学生登陆主界面 7 2.2管理员登陆主界面 8 2.3 学生考试系统实现 9 2.4学生练习系统实现 10 2.5试题管理系统实…