瀑布流布局 (初版)

news2025/2/25 17:13:32

瀑布流布局


文章目录

  • 瀑布流布局
  • 前言
    • 1. 背景
    • 2. 点⬇️🔗去体验
      • 效果如下图所示:
  • 一、初版waterfall布局和问题暴露?
    • 1.效果图如下:
    • 2.暴露问题如下图所示:
      • 第一张问题图:
      • 第二张问题图:
    • 3.HTML代码如下:
    • 4.JS代码如下:
  • 二、初版waterfall布局问题的排查和解决
    • 1.排查问题
    • 2.解决问题
      • 第一种解决方法:设置块级作用域(行不通)
        • 代码修改如下图所示:
        • 修改后如下图所示(依然有插入顺序问题):
      • 第二种解决方法:改变每一列高度的获取方式(成功了)
        • 代码修改如下图所示:
        • 图1如下(waterfall布局正常渲染)
        • 图2如下(waterfall布局正常渲染)
    • 3.完整代码 👇方🔗获取
  • 总结(完整代码文件点击下方🔗,晚些更新进阶版)


前言

起初我看网上有很多处理waterfall的处理方案,但是我都没去仔细的去阅读📖(主要是我相信我自己也可以做出来,事实如此我做出来了)。
后面也可能会对当前的版本进行二次优化学习一下别人的优秀想法💡。

⚠️⚠️⚠️:提供这个容易理解的版本,后续会发布精简版本或者附加功能版本
(功能包括:图片懒加载触底加载数据展示的虚拟列表优化响应式等功能。

1. 背景

为什么突然要去尝试写一个瀑布流布局?

  1. 首先,很早之前我就看到【小红书】主站就采用了这种 waterfall布局进行的展示。
    其次,负责这块内容的同学是我前一个组的同事(哈哈哈哈哈😂)。
    然后,我就大概去调试了一下【小红书】主站上的瀑布流,第一感觉:那是相当的丝滑,很牛逼,很高大上;
    最后,waterfall布局也可以搭配很多其他的功能,例如:触底加载,图片懒加载,Dom结构懒加载等。
  1. 【小红书】主战的waterfall布局他使用的是 绝对定位 + Css的样式进行开发的。这种waterfall布局的优势:就是可以避免当前的网页一直被重绘。古德古德!!💪💪

2. 点⬇️🔗去体验

waterfall体验🤌

效果如下图所示:

在这里插入图片描述


一、初版waterfall布局和问题暴露?

1.效果图如下:

请添加图片描述

2.暴露问题如下图所示:

  1. 在首页中也可以看到错误的顺序。
  2. 初版构思的waterfall布局,并没有按照最小的长度的盒子的顺序插入,而是一个比较乱的状态

第一张问题图:

在这里插入图片描述

第二张问题图:

在这里插入图片描述

3.HTML代码如下:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>waterFall</title>
    <style>
        #water-fall-main {
            display: flex;
            gap: 8px;
            position: relative;
            width: 100%;
            justify-content: space-around;
        }

        .water-fall-columns {
            width: 250px;
            /* border: 1px solid red; */
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 8px;
        }

        .water-fall-item {
            width: 232px;
        }
    </style>
</head>

<body>
    <div id="water-fall-main">
    </div>
</body>

</html>

4.JS代码如下:

  //获取瀑布流的主元素
    const waterFallMain = document.querySelector('#water-fall-main')
    const createDomContainer = []
    const setCurrentPageColumns = (width) => {
        const currentOutterWidth = width

        return Math.floor(currentOutterWidth / 250)
    }
    const setRangeWidth = () => {
        const height = Math.floor(Math.random() * 450)
        return height > 225 ? height : 200
    }
    const setRandomWaterItemNumber = () => {
        const number = Math.floor(Math.random() * 100)
        return number > 25 ? number : 50
    }
    const setRandomColor = () => {
        const colorArr = ['#f39999', '#7f5555', '#94eca1', '#dd9757', '#98f2b0', '#75e1ef', '#5e47e8', '#c652ef',]
        return colorArr[Math.floor(Math.random() * colorArr.length)]
    }




    //第一次进入页面渲染的盒子
    const defaultRender = () => {
        const columnsNumber = setCurrentPageColumns(document.body.clientWidth)
        for (let index = 1; index < columnsNumber; index++) {
            const div = document.createElement('div')
            div.className = 'water-fall-columns'
            createDomContainer.push(div)
            waterFallMain.appendChild(div)
        }
        const domArrLength = createDomContainer.map(container => container.offsetHeight);
        const numbersItem = setRandomWaterItemNumber()
        for (let index = 0; index < numbersItem; index++) {
            const domContent = document.querySelectorAll('.water-fall-columns')
            const div = document.createElement('div')
            const height = setRangeWidth()
            div.style.height = height + 'px'
            div.style.backgroundColor = setRandomColor()
            div.className = 'water-fall-item'
            div.innerText = index + 1
            let resultLength = domArrLength.reduce((pre, cur, curIndex) => {
                return pre > cur ? cur : pre;
            }, domArrLength[0])
            let lastIndex = domArrLength.indexOf(resultLength)

            const allBox = document.querySelectorAll('.water-fall-columns')
            allBox.forEach((v, k) => {
                if (k === lastIndex) {
                    v.appendChild(div)
                    domArrLength[k] = v.offsetHeight
                }
            })
        }

    }


二、初版waterfall布局问题的排查和解决

1.排查问题

  1. 首先我通过上面的位置错误,可以显而易见的发现是每个盒子的高度获取或者插入盒子的位置, 二者其中一个存在一定的问题。
  2. 然后经过排查,发现通过dom.offsetHeight这个属性获取盒子的时候,并不能返回当前盒子的高度,而且会出现前一个盒子的offsetHeight居然在遍历的过程中影响到后面的盒子高度(偶尔发生),所以就导致了出现上面的情况。

2.解决问题

从排查的问题的结果中发现,是因为每一列的高度计算出现了问题!!!!!!!所以这个时候就好办了。

第一种解决方法:设置块级作用域(行不通)

因为是获取高度出现的问题,有没有一种可能🤔:是没有块级作用域导致的问题?
我紧接着就进行了尝试。

代码修改如下图所示:

在这里插入图片描述

修改后如下图所示(依然有插入顺序问题):

头部的图是这样,尾部的图也是与前端一致的,所以果断放弃了往这方面思考🤔

在这里插入图片描述

第二种解决方法:改变每一列高度的获取方式(成功了)

因为是要计算每一列的高度,所以我从原来获取插入后的高度===》插入一个元素就在当前列添加这个元素的高度,实现一个累加的效果。

代码修改如下图所示:

在这里插入图片描述

图1如下(waterfall布局正常渲染)

在这里插入图片描述

图2如下(waterfall布局正常渲染)

在这里插入图片描述

3.完整代码 👇方🔗获取

点我跳转


总结(完整代码文件点击下方🔗,晚些更新进阶版)

从开始接触这个功能 ➡️➡️ 构思解决方案 ➡️➡️ 解决方案验证 ➡️➡️ 方案基本实现 ➡️➡️ 问题发现 ➡️➡️
解决问题。整个流程下来呢,合计不超过1.5d。更多的是思考需要的时间会更加的多。

完整的代码请点击👉🔗

希望大家都可以找到自己感兴趣的事情,💪💪💪!!!!!

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

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

相关文章

Linux的权限(三)

目录 共享文件夹 分析一 补充内容 分析二 粘滞位 共享文件夹 分析一 在普通用户yyf中创建一个目录test&#xff1a; 普通用户yyf在test目录中创建yyf类的文件&#xff0c;超级用户root在该目录中创建root.txt类的文件&#xff08;从拥有者和所属组上来看只有root可以对这…

博弈论(牛客练习赛)

思路&#xff1a;我们考虑小念赢 1、如果n>1并且p0&#xff0c;小念可以连续取两次&#xff0c;相当于小念有挂&#xff0c;可以从必败态转为必胜态&#xff0c;必赢。 2、如果n>1并且m>n-1&#xff0c;小念第一次取n-1个&#xff0c;小念必赢。 代码&#xff1a; …

【覆盖率类型 覆盖策略覆盖组_2023.01.26】

覆盖率类型 覆盖率&#xff1a;衡量设计验证的完备性 代码覆盖率 检测对设计代码运行程度的衡量&#xff0c;达到100%并不代表验证的工作已经完成&#xff08;可能某些功能并未设计&#xff09; line coverage paths coverage toggle coverage//所有变量都有过0&#xff0c…

Java-List接口常用方法和遍历方法

List的继承结构 其中&#xff0c;红色为接口&#xff0c;蓝色为实现类 List的四大方法 List的基本操作void add(int index,E e)boolean remove(Object o)E remove(int index)E set(int index,E e)E get(int index)其中注意删除方法有两种&#xff0c;执行的时候主要选择实参…

爬虫(滑块验证的破解)

基于滑块的验证破解 —— Selenium 1.可分为三个核心步骤 获取验证码图片识别图片&#xff0c;计算轨迹距离寻找滑块&#xff0c;控制滑动 打开网址&#xff1a;https://www.geetest.com/adaptive-captcha-demo 2.获取验证图片 import re import time from selenium import…

OSPF协议基础(OSPF工作过程)

目录 OSPF基本工作原理邻居建立过程Router ID发现并建立邻居 - Hello报文OSPF邻居建立过程 链路状态信息丰富的数据链路层支持能力网络类型 - P2P网络网络类型 - 广播型网络网络类型 - NBMA网络网络类型 - P2MP网络OSPF的度量方式 报文类型及作用OSPF协议报文头部OSPF报文类型O…

推荐几款便宜幻兽帕鲁游戏联机服务专用云服务器

随着互联网技术的发展&#xff0c;云服务器已经成为了许多游戏联机服务的首选。如果大家想要自行搭建幻兽帕鲁联机服务器&#xff0c;那么使用云服务器是一个很好的选择。下面&#xff0c;本文将推荐几款便宜幻兽帕鲁游戏联机服务专用云服务器。 幻兽帕鲁游戏对于服务器配置要求…

Linux中的LVM理论

Linux LVM&#xff1a;Logical Volume Manager逻辑卷管理 无需在停机的情况下&#xff0c;动态调整分区的大小 PV里面的存在很多小方块PE&#xff08;物理扩展&#xff09;&#xff0c;一个PV继承了pp的100G&#xff0c;只不过被分开分配了 划分小的PE再存放在VG里面&#…

Chrome单独配置代理的方法

Windows Windows上单独对Chrome设置代理&#xff0c;需要在启动时传递参数&#xff0c;具体步骤如下。 在Chrome浏览器的快捷方式上右击&#xff0c;进入属性。在 快捷方式 标签下找到 目标 项目&#xff0c;在最后添加 –proxy-server“socks5://xxx.xxx.xx.xx:xxxx” 如果要…

幻兽帕鲁服务器一键搭建脚本

前言 幻兽帕鲁刚上线就百万在线人数。官方服务器的又经常不稳定。所以这里给大家带来最快捷的搭建教程。废话不多说直接开始。 服务器配置要求 这里推荐腾讯云的轻量云服务器 测试环境&#xff1a; CPU &#xff1a; 2核 内存&#xff1a;4GB 系统&#xff1a;Debian 12 64…

vue实现甘特图

目录 实现效果 一、安装依赖 二、使用 二、绕过license 实现效果 一、安装依赖 npm i --save vue-gantt-schedule-timeline-calendar 实现甘特图需先安装上述依赖&#xff0c;安装依赖实际上是通过gantt-schedule-timeline-calendar来实现的。所以node_module中因包含以下…

支持IPv4与IPv6双协议栈的串口服务器,IPv6串口服务器

物联网是啥玩意儿&#xff1f;这是首先要搞明白的。按照百度百科的说法&#xff0c;是将各种信息传感设备&#xff0c;如射频识别&#xff08;RFID&#xff09;装置、红外感应器、全球定位系统、激光扫描器等种种装置与互联网结合起来而形成的一个巨大网络。这个说法有些复杂&a…

浅析Redis②:命令处理之epoll实现(中)

写在前面 Redis作为我们日常工作中最常使用的缓存数据库&#xff0c;其重要性不言而喻&#xff0c;作为普通开发者&#xff0c;我们在日常开发中使用Redis&#xff0c;主要聚焦于Redis的基层数据结构的命令使用&#xff0c;很少会有人对Redis的内部实现机制进行了解&#xff0c…

2024最新幻兽帕鲁服务器多少钱一个?

幻兽帕鲁服务器多少钱&#xff1f;价格便宜&#xff0c;阿里云4核16G幻兽帕鲁专属服务器32元1个月、66元3个月&#xff0c;4核32G配置113元1个月、339元3个月&#xff1b;腾讯云4核16G14M服务器66元1个月、277元3个月、1584元一年。阿腾云atengyun.com分享阿里云和腾讯云palwor…

Java面试题之序列化和反序列化

Java面试题之序列化和反序列化 文章目录 Java面试题之序列化和反序列化序列化和反序列化什么是序列化?什么是反序列化?如果有些字段不想进行序列化怎么办&#xff1f;常见序列化协议有哪些&#xff1f;为什么不推荐使用 JDK 自带的序列化&#xff1f; 文章来自Java Guide 用于…

快乐学Python,DataFrame的基本操作

在上一篇文章中&#xff0c;我们了解了如何使用 pandas 的函数来从多种数据源&#xff1a;csv、excel 和 html 网页。其中不管是哪一种数据读取的方式&#xff0c;最终返回的都是一个 DataFrame 对象。 对于 DataFrame 对象&#xff0c;我们只是简单将其打印出来&#xff0c;这…

Mac M1 Parallels CentOS7.9 Deploy 禅道

禅道官网下载地址: https://www.zentao.net/download/max4.10-83276.html 一、官网下载 二、解压安装 将下载好的包传至CentOS7.9虚拟机 zhinian192 ~ % scp Downloads/ZenTaoPMS-max4.10-zbox_arm64.tar.gz root10.211.55.36:~ ZenTaoPMS-max4.10-zbox_arm64.tar.gz …

分享5款专注于实用功能的小众软件

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.视频播放——Potplayer ​ Potplayer是一款功能强大的视频播放软件&#xff0c;支持各种格式的视频文…

Stable Diffusion插件Recolor实现黑白照片上色

今天跟大家分享一个使用Recolor插件通过SD实现老旧照片轻松变彩色&#xff0c;Recolor翻译过来的含义就是重上色&#xff0c;该模型可以保持图片的构图&#xff0c;它只会负责上色&#xff0c;图片不会发生任何变化。 一&#xff1a;插件下载地址 https://github.com/pkuliyi…

eNSP学习——利用三层交换机实现VLAN间路由

目录 背景 实验内容 实验目的 实验步骤 实验拓扑 实验编址 实验步骤 基本配置 配置三层交换机实现VLAN间通信 背景 虽说单臂路由可以实现不同VLAN之间主机的通信&#xff0c;但该技术存在一些局限性&#xff0c;比如带宽、转发效率等。 三层交换机在原有二层交换机…