也许是最简单的纯 CSS 实现瀑布流布局优化版!!!

本文探讨了如何使用CSS和JavaScript实现瀑布流布局,以解决columns布局的局限。通过创建多个列并利用排序算法,使得元素按特定顺序填充,同时结合懒加载实现流畅的滚动效果。代码示例详细展示了整个过程,适用于前端开发中的布局设计。
摘要由CSDN通过智能技术生成

效果图

在这里插入图片描述

前言

本篇实现是对于上一篇 也许是最简单的纯 CSS 实现瀑布流布局!!! 中以 columns 多列布局 实现瀑布流所存在的局限进行解决,这里的布局参考了一下蘑菇街 的实现。

HTML&CSS

<style>
    .box-wrapper {
        display: flex;
    }

    .column-box {
        flex: 1;
        margin-right: 20px;
    }

    .box-wrapper .column-box:last-child {
        margin-right: 0;
    }
</style>
<div class="box-wrapper">
    <div class="column-box"></div>
    <div class="column-box"></div>
    <div class="column-box"></div>
    <div class="column-box"></div>
</div>

以上只是为了实现下述这张图,然后将一些高度不一的盒子加进去便实现了瀑布流:

在这里插入图片描述

那么实现瀑布流的关键无非就这几种:多列、元素参差不齐排列、懒加载。不同于 columns 布局的是,上述的布局需要将子元素添加到多个父级中,并且要实现符合我们日常场景的排序。也不难,代码如下:

排序

符合我们日常场景的排序:排序1的放在第一个长条里,排序2的放在第二个长条里,排序3的放在第三个长条里,排序4的放在第四个长条里,依次循环类推……也不难写出下面代码:

let counter = 0
let arrays = [[], [], [], []]

function pushItem(current, arrIndex) {
    current % 4 === arrIndex && arrays[arrIndex].push(++counter)
}

for (let i = 0; i < 20; i++) {
    pushItem(i, 0)
    pushItem(i, 1)
    pushItem(i, 2)
    pushItem(i, 3)
}

console.log(arrays);
// [
//     [ 1, 5, 9, 13, 17 ],
//     [ 2, 6, 10, 14, 18 ],
//     [ 3, 7, 11, 15, 19 ],
//     [ 4, 8, 12, 16, 20 ]
// ]

完整JS

通过上述的排序代码结合上一篇的 js 实现代码,稍改后的 js 代码如下:

<script>
    let counter = 0
    const INITIAL_NUMBER = 40
    const MAX_HEIGHT = 400
    const MIN_HEIGHT = 200
    const columnBoxList = document.querySelectorAll('.column-box')


    function createDiv() {
        const div = document.createElement('div')
        const randomHeight = Math.floor(Math.random() * (MAX_HEIGHT - MIN_HEIGHT + 1) + MIN_HEIGHT)
        div.innerHTML = `${++counter}`
        div.style.height = `${randomHeight}px`
        div.classList.add('box-item')
        return div
    }

    function createFragments(num) {
        const fragments = []

        for (let j = 0; j < 4; j++) {
            fragments.push(document.createDocumentFragment())
        }

        function pushItem(current, arrIndex) {
            current % 4 === arrIndex && fragments[arrIndex].appendChild(createDiv())
        }

        for (let i = 0; i < num; i++) {
            pushItem(i, 0)
            pushItem(i, 1)
            pushItem(i, 2)
            pushItem(i, 3)
        }

        return fragments
    }

    function createLoading() {
        let loading = document.querySelector('.loading')
        if (!loading) {
            loading = document.createElement('div')
            loading.classList.add('loading')
        }
        return loading
    }

    function appendHandler(num) {
        const elements = createFragments(num)
        columnBoxList.forEach((column, i) => {
            column.appendChild(elements[i])
        })
    }

    function init() {
        appendHandler(INITIAL_NUMBER)
    }

    function scrollHandler() {
        const {scrollTop, clientHeight, offsetHeight} = document.documentElement
        const nearBottom = offsetHeight - clientHeight === scrollTop

        if (nearBottom) {
            const loading = createLoading()
            document.body.appendChild(loading)
            setTimeout(() => {
                document.body.removeChild(loading)
                appendHandler(20)
            }, 1000)
        }
    }

    function debounce(callback, delay) {
        let timer = null
        return function () {
            clearTimeout(timer)
            timer = setTimeout(callback, delay)
        }
    }

    window.addEventListener('load', init)
    window.addEventListener('scroll', debounce(scrollHandler, 100))
</script>

子元素的高度差异不要过大,这样的排序效果还是非常符合我们的日常直觉的。以上便是我探索 瀑布流布局 的全部了,更详细的代码点击 这里

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

帝尊菜鸟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值