瀑布流布局 (初版)
瀑布流布局
文章目录
- 瀑布流布局
- 前言
- 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…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...