当前位置: 首页 > news >正文

瀑布流布局 (初版)

瀑布流布局


文章目录

  • 瀑布流布局
  • 前言
    • 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 = 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.排查问题

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

2.解决问题

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

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

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

代码修改如下图所示:

在这里插入图片描述

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

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

在这里插入图片描述

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

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

代码修改如下图所示:

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

3.完整代码 👇方🔗获取

点我跳转


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

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

完整的代码请点击👉🔗

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

相关文章:

瀑布流布局 (初版)

瀑布流布局 文章目录 瀑布流布局前言1. 背景2. 点⬇️&#x1f517;去体验效果如下图所示&#xff1a; 一、初版waterfall布局和问题暴露&#xff1f;1.效果图如下&#xff1a;2.暴露问题如下图所示&#xff1a;第一张问题图&#xff1a;第二张问题图&#xff1a; 3.HTML代码如…...

硕士毕业论文写作笔记

一、写作顺序 1.标题、研究问题、研究方法 2.文献综述&#xff08;占比1/5-1/6&#xff09; 3.论证章节 4.结论、不足、启示 5.处理图表、参考文献的格式 6.绪论或引言 7.摘要、关键词 8.查重、装订 http://【硕士毕业论文写不下去&#xff0c;多亏听了张博士的论文写…...

成本更低、更可控,云原生可观测新计费模式正式上线

云布道师 在上云开始使用云产品过程中&#xff0c;企业一定遇见过两件“讨厌”事&#xff1a; 难以理解的复杂计费逻辑&#xff0c;时常冒出“这也能收费”的感叹&#xff1b; 某个配置参数调节之后&#xff0c;云产品使用成本不可预估的暴涨。 可观测作为企业 IT 运维必须品…...

5.列表选择弹窗(BottomListPopup)

愿你出走半生,归来仍是少年&#xff01; 环境&#xff1a;.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++)

原型模式 原型模式就是就是对对象的克隆。有一些私有变量外界难以访问&#xff0c;而原型模式可以做到对原型一比一的复刻。 其关键代码为下面的clone方法。此方法将本对象进行复制传递出去。 class ConcretePrototype1 : public Prototype{ public:ConcretePrototype1(stri…...

Python基础之数据库操作

一、安装第三方库PyMySQL 1、在PyCharm中通过 【File】-【setting】-【Python Interpreter】搜索 PyMySQL进行安装 2、通过PyCharm中的 Terminal 命令行 输入: pip install PyMySQL 注&#xff1a;通过pip安装&#xff0c;可能会提示需要更新pip&#xff0c;这时可执行&#…...

redis-发布缓存

一.redis的发布订阅 什么 是发布和订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 Redis的发布和订阅 客户端订阅频道发布的消息 频道发布消息 订阅者就可…...

Stata17安装教程

文章目录 **Stata17安装教程**前言系统要求Windows&#xff1a;macOS&#xff1a;Linux&#xff1a; 软件下载正式安装1.下载Stata 17安装包2.双击Stata17.exe开启安装3.接受同意条款&#xff0c;然后继续安装4.选择想要安装的版本&#xff0c;Stata BE为基础版、Stata SE为特别…...

Java PDFBox 提取页数、PDF转图片

PDF 提取 使用Apache 的pdfbox组件对PDF文件解析读取和转图片。 Maven 依赖 导入下面的maven依赖&#xff1a; <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.30</version> &l…...

【代码随想录14】104.二叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数

目录 104.二叉树的最大深度题目描述参考代码 111.二叉树的最小深度题目描述参考代码 222.完全二叉树的节点个数题目描述参考代码 104.二叉树的最大深度 题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径…...

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&#xff0c;现在已经可以闭眼操作了哈哈&#x1f61d;。我原本以为大家都已经用上GPT4&#xff0c;享受着它带来的巨大帮助时&#xff0c;但结果还挺让我吃惊的&#xff0c;还是有很多人仍苦于如何进行升级。所以就想着写篇教程来教会大家如何…...

幻兽帕鲁服务器数据备份

搭建幻兽帕鲁个人服务器&#xff0c;最近不少用户碰到内存不足、游戏坏档之类的问题。做好定时备份&#xff0c;才能轻松快速恢复游戏进度 这里讲一下如何定时将服务器数据备份到腾讯云轻量对象存储服务&#xff0c;以及如何在有需要的时候进行数据恢复。服务器中间的数据迁移…...

【Digester解析XML文件的三种方式】

Digester解析XML文件的三种方式 1. Digester解析XML文件的三种方式1.1 作用及依赖jar包 2. 重点和难点3. XML文件4. 通过不同的方式解析这个xml文件4.1 通过java编码方式解析&#xff08;javabean存储&#xff09;4.2 通过java编码方式解析&#xff08;list和map存储&#xff0…...

MATLAB curve fitting toolbox没有怎么办?

版本&#xff1a;MATLAB R2023b 如果在安装MATLAB时仅仅选择了安装MATLAB&#xff0c;而并未选择其他选项&#xff0c;则在进入MATLAB后会发现顶部的APP栏中无法找到曲线拟合工具箱。 本人跟随MATLAB中的教程进行下载时&#xff0c;出现了如下报错&#xff1a; 最终解决方案&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&#xff08;这个命令尽量在少量用户使用此软件时运行&#xff0c;因为此命令是真的读磁盘…...

Spring框架中的设计模式

&#x1f389;欢迎来到Spring专栏&#xff1a;Spring框架中的设计模式 &#x1f4dc;其他专栏&#xff1a;java面试 数据结构 源码解读 故障分析 &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是小徐&#x1f947;☁️博客首页&#xff1a;CSDN主页小徐的博客&#x…...

Java数据结构与算法:邻接矩阵和邻接表

Java数据结构与算法&#xff1a;邻接矩阵和邻接表 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 什么是邻接矩阵和邻接表&#xff1f; 在图的表示中&#xff0c…...

【温故而知新】JavaScript类、类继承、静态方法

文章目录 前言一、类二、类继承三、静态方法四、热门文章 前言 JavaScript是一种广泛使用的编程语言&#xff0c;主要用于Web开发。它是一种脚本语言&#xff0c;这意味着它不需要像编译语言那样预先编译&#xff0c;而是在运行时解释和执行。JavaScript可以直接在浏览器中运行…...

小黑艰难的前端啃bug之路:内联元素之间的间隙问题

今天开始学习前端项目&#xff0c;遇到了一个Bug调了好久&#xff0c;即使margin为0&#xff0c;但还是有空格。 小黑整理&#xff0c;用四种方法解决了空白问题 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></tit…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...