瀑布流布局 (初版)

本文详细描述了作者从模仿小红书瀑布流布局开始,遇到问题并逐步排查、解决的过程,涉及HTML、CSS和JavaScript代码修改,最终实现瀑布流效果并分享完整代码。
摘要由CSDN通过智能技术生成

瀑布流布局



前言

起初我看网上有很多处理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。更多的是思考需要的时间会更加的多。

完整的代码请点击👉🔗

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

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
引用\[1\]: 企业微信上介绍了自建流媒体的功能,但经过本人的研究测试发现,该工作流引擎的功能是比较有限的。它只能在移动端发起,流程的定义必须在企业微信控制台中定义,而且不支持条件分支,适用于比较简单的应用场景,如请假等。此外,审批界面的数据展示自定义程度也很低。\[1\] 引用\[2\]: 在企业微信开发中,需要使用一些基础信息来进行开发。每个企业都有唯一的corpid,可以在企业微信管理后台的“我的企业”-“企业信息”下查看。每个应用也有唯一的agentid,可以在管理后台的“应用与小程序”-“应用”中找到。为了保证数据安全,每个应用都有一个独立的secret作为访问密钥。在通信时,需要携带access_token来验证接口的访问权限。\[2\] 引用\[3\]: 在审批流引擎开发中,可以通过获取文件流并转换为字节数组的方式来处理文件。可以使用Java的URL类来获取文件流,并将其转换为字节数组。具体代码如下所示: ```java import java.net.URL; import java.io.InputStream; import java.io.IOException; String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=xxxxxxxxxxxxxxxxxxx&media_id=xxxxxxxx"; InputStream in; byte\[\] image = new byte\[0\]; try { URL uri = new URL(url); in = uri.openStream(); byte\[\] buf = new byte\[1024\]; while (in.read(buf) > 0) { image = Utils.byteMerger(image, buf); } in.close(); } catch (IOException e) { e.printStackTrace(); } ``` 以上代码可以用于获取文件流并将其转换为字节数组。\[3\] 综上所述,企业微信自建流媒体功能的使用有一定的限制,开发时需要使用一些基础信息,并可以通过获取文件流并转换为字节数组的方式来处理文件。 #### 引用[.reference_title] - *1* *2* [企业微信开发实战:自建审批流引擎](https://blog.csdn.net/qq_31587795/article/details/102813718)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [[企业微信二次开发]自建应用API获取媒体文件(初版)](https://blog.csdn.net/weixin_43303530/article/details/115959431)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

满脑子技术的前端工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值