瀑布流布局 (初版)
瀑布流布局
文章目录
- 瀑布流布局
- 前言
- 1. 背景
- 2. 点⬇️🔗去体验
- 效果如下图所示:
- 一、初版waterfall布局和问题暴露?
- 1.效果图如下:
- 2.暴露问题如下图所示:
- 第一张问题图:
- 第二张问题图:
- 3.HTML代码如下:
- 4.JS代码如下:
- 二、初版waterfall布局问题的排查和解决
- 1.排查问题
- 2.解决问题
- 第一种解决方法:设置块级作用域(行不通)
- 代码修改如下图所示:
- 修改后如下图所示(依然有插入顺序问题):
- 第二种解决方法:改变每一列高度的获取方式(成功了)
- 代码修改如下图所示:
- 图1如下(waterfall布局正常渲染)
- 图2如下(waterfall布局正常渲染)
- 3.完整代码 👇方🔗获取
- 总结(完整代码文件点击下方🔗,晚些更新进阶版)
前言
起初我看网上有很多处理waterfall的处理方案,但是我都没去仔细的去阅读📖
(主要是我相信我自己也可以做出来,事实如此我做出来了)。
后面也可能会对当前的版本进行二次优化。学习一下别人的优秀想法💡。
⚠️⚠️⚠️:
提供这个容易理解的版本,后续会发布精简版本或者附加功能版本
(功能包括:图片懒加载、触底加载数据、展示的虚拟列表优化、响应式等功能。
1. 背景
为什么突然要去尝试写一个瀑布流布局?
首先,很早之前我就看到【小红书】主站就采用了这种 waterfall布局进行的展示。
其次,负责这块内容的同学是我前一个组的同事(哈哈哈哈哈😂)。
然后,我就大概去调试了一下【小红书】主站上的瀑布流,第一感觉:那是相当的丝滑,很牛逼,很高大上;
最后,waterfall布局也可以搭配很多其他的功能,例如:触底加载,图片懒加载,Dom结构懒加载等。
- 【小红书】主战的waterfall布局他使用的是
绝对定位 + Css的样式进行开发的。这种waterfall布局的优势:就是可以避免当前的网页一直被重绘。古德古德!!💪💪
2. 点⬇️🔗去体验
waterfall体验🤌
效果如下图所示:

一、初版waterfall布局和问题暴露?
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 = widthreturn 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 + 1let 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.排查问题
- 首先我通过上面的位置错误,可以显而易见的发现是
每个盒子的高度获取或者插入盒子的位置, 二者其中一个存在一定的问题。- 然后经过排查,发现通过dom.offsetHeight这个属性获取盒子的时候,并不能返回当前盒子的高度,而且会出现
前一个盒子的offsetHeight居然在遍历的过程中影响到后面的盒子高度(偶尔发生),所以就导致了出现上面的情况。
2.解决问题
从排查的问题的结果中发现,是因为每一列的高度计算出现了问题!!!!!!!所以这个时候就好办了。
第一种解决方法:设置块级作用域(行不通)
因为是获取高度出现的问题,有没有一种可能🤔:是没有块级作用域导致的问题?
我紧接着就进行了尝试。
代码修改如下图所示:

修改后如下图所示(依然有插入顺序问题):
头部的图是这样,尾部的图也是与前端一致的,所以果断放弃了往这方面思考🤔

第二种解决方法:改变每一列高度的获取方式(成功了)
因为是要计算每一列的高度,所以我从原来获取插入后的高度===》插入一个元素就在当前列添加这个元素的高度,实现一个累加的效果。
代码修改如下图所示:

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

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

3.完整代码 👇方🔗获取
点我跳转
总结(完整代码文件点击下方🔗,晚些更新进阶版)
从开始接触这个功能 ➡️➡️ 构思解决方案 ➡️➡️ 解决方案验证 ➡️➡️ 方案基本实现 ➡️➡️ 问题发现 ➡️➡️
解决问题。整个流程下来呢,合计不超过1.5d。更多的是思考需要的时间会更加的多。
完整的代码请点击👉🔗
希望大家都可以找到自己感兴趣的事情,💪💪💪!!!!!
相关文章:
瀑布流布局 (初版)
瀑布流布局 文章目录 瀑布流布局前言1. 背景2. 点⬇️🔗去体验效果如下图所示: 一、初版waterfall布局和问题暴露?1.效果图如下:2.暴露问题如下图所示:第一张问题图:第二张问题图: 3.HTML代码如…...
硕士毕业论文写作笔记
一、写作顺序 1.标题、研究问题、研究方法 2.文献综述(占比1/5-1/6) 3.论证章节 4.结论、不足、启示 5.处理图表、参考文献的格式 6.绪论或引言 7.摘要、关键词 8.查重、装订 http://【硕士毕业论文写不下去,多亏听了张博士的论文写…...
成本更低、更可控,云原生可观测新计费模式正式上线
云布道师 在上云开始使用云产品过程中,企业一定遇见过两件“讨厌”事: 难以理解的复杂计费逻辑,时常冒出“这也能收费”的感叹; 某个配置参数调节之后,云产品使用成本不可预估的暴涨。 可观测作为企业 IT 运维必须品…...
5.列表选择弹窗(BottomListPopup)
愿你出走半生,归来仍是少年! 环境:.NET 7、MAUI 从底部弹出的列表选择弹窗。 1.布局 <?xml version"1.0" encoding"utf-8" ?> <toolkit:Popup xmlns"http://schemas.microsoft.com/dotnet/2021/maui"xmlns…...
(十三)Head first design patterns原型模式(c++)
原型模式 原型模式就是就是对对象的克隆。有一些私有变量外界难以访问,而原型模式可以做到对原型一比一的复刻。 其关键代码为下面的clone方法。此方法将本对象进行复制传递出去。 class ConcretePrototype1 : public Prototype{ public:ConcretePrototype1(stri…...
Python基础之数据库操作
一、安装第三方库PyMySQL 1、在PyCharm中通过 【File】-【setting】-【Python Interpreter】搜索 PyMySQL进行安装 2、通过PyCharm中的 Terminal 命令行 输入: pip install PyMySQL 注:通过pip安装,可能会提示需要更新pip,这时可执行&#…...
redis-发布缓存
一.redis的发布订阅 什么 是发布和订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 Redis的发布和订阅 客户端订阅频道发布的消息 频道发布消息 订阅者就可…...
Stata17安装教程
文章目录 **Stata17安装教程**前言系统要求Windows:macOS:Linux: 软件下载正式安装1.下载Stata 17安装包2.双击Stata17.exe开启安装3.接受同意条款,然后继续安装4.选择想要安装的版本,Stata BE为基础版、Stata SE为特别…...
Java PDFBox 提取页数、PDF转图片
PDF 提取 使用Apache 的pdfbox组件对PDF文件解析读取和转图片。 Maven 依赖 导入下面的maven依赖: <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.30</version> &l…...
【代码随想录14】104.二叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数
目录 104.二叉树的最大深度题目描述参考代码 111.二叉树的最小深度题目描述参考代码 222.完全二叉树的节点个数题目描述参考代码 104.二叉树的最大深度 题目描述 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径…...
AWS 专题学习 P10 (Databases、 Data Analytics)
文章目录 专题总览1. Databases1.1 选择合适的数据库1.2 数据库类型1.3 AWS 数据库服务概述Amazon RDSAmazon AuroraAmazon ElastiCacheAmazon DynamoDBAmazon S3DocumentDBAmazon NeptuneAmazon Keyspaces (for Apache Cassandra)Amazon QLDBAmazon Timestream 2. Data & …...
一键拥有你的GPT4
这几天我一直在帮朋友升级ChatGPT,现在已经可以闭眼操作了哈哈😝。我原本以为大家都已经用上GPT4,享受着它带来的巨大帮助时,但结果还挺让我吃惊的,还是有很多人仍苦于如何进行升级。所以就想着写篇教程来教会大家如何…...
幻兽帕鲁服务器数据备份
搭建幻兽帕鲁个人服务器,最近不少用户碰到内存不足、游戏坏档之类的问题。做好定时备份,才能轻松快速恢复游戏进度 这里讲一下如何定时将服务器数据备份到腾讯云轻量对象存储服务,以及如何在有需要的时候进行数据恢复。服务器中间的数据迁移…...
【Digester解析XML文件的三种方式】
Digester解析XML文件的三种方式 1. Digester解析XML文件的三种方式1.1 作用及依赖jar包 2. 重点和难点3. XML文件4. 通过不同的方式解析这个xml文件4.1 通过java编码方式解析(javabean存储)4.2 通过java编码方式解析(list和map存储࿰…...
MATLAB curve fitting toolbox没有怎么办?
版本:MATLAB R2023b 如果在安装MATLAB时仅仅选择了安装MATLAB,而并未选择其他选项,则在进入MATLAB后会发现顶部的APP栏中无法找到曲线拟合工具箱。 本人跟随MATLAB中的教程进行下载时,出现了如下报错: 最终解决方案&a…...
Linux之快速入门(CentOS 7)
文章目录 一、Linux目录结构二、常用命令2.1 切换用户2.2查看ip地址2.3 cd2.4 目录查看2.5 查看文件内容2.6 创建目录及文件2.7 复制和移动2.8 其他2.9 tar3.0 which3.1 whereis3.2 find(这个命令尽量在少量用户使用此软件时运行,因为此命令是真的读磁盘…...
Spring框架中的设计模式
🎉欢迎来到Spring专栏:Spring框架中的设计模式 📜其他专栏:java面试 数据结构 源码解读 故障分析 🎬作者简介:大家好,我是小徐🥇☁️博客首页:CSDN主页小徐的博客&#x…...
Java数据结构与算法:邻接矩阵和邻接表
Java数据结构与算法:邻接矩阵和邻接表 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 什么是邻接矩阵和邻接表? 在图的表示中,…...
【温故而知新】JavaScript类、类继承、静态方法
文章目录 前言一、类二、类继承三、静态方法四、热门文章 前言 JavaScript是一种广泛使用的编程语言,主要用于Web开发。它是一种脚本语言,这意味着它不需要像编译语言那样预先编译,而是在运行时解释和执行。JavaScript可以直接在浏览器中运行…...
小黑艰难的前端啃bug之路:内联元素之间的间隙问题
今天开始学习前端项目,遇到了一个Bug调了好久,即使margin为0,但还是有空格。 小黑整理,用四种方法解决了空白问题 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></tit…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
