使用JS实现图片的瀑布流布局效果

代码展示
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>瀑布流布局</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

    .container {
        width: 100%;
        padding: 20px;
        background-color: #f5f5f5;
    }

    .waterfall {
        position: relative;
        width: 100%;
    }

    .item {
        position: absolute;
        width: calc(25% - 20px);
        margin: 10px;
        background: #fff;
        border-radius: 8px;
        overflow: hidden;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        transition: all 0.3s ease;
    }

    .item:hover {
        transform: translateY(-5px);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    .item img {
        width: 100%;
        display: block;
    }

    .item .content {
        padding: 10px;
    }

    .item .title {
        font-size: 16px;
        margin-bottom: 5px;
    }

    .item .desc {
        font-size: 14px;
        color: #666;
    }

    @media screen and (max-width: 1200px) {
        .item {
            width: calc(33.33% - 20px);
        }
    }

    @media screen and (max-width: 768px) {
        .item {
            width: calc(50% - 20px);
        }
    }

    @media screen and (max-width: 480px) {
        .item {
            width: calc(100% - 20px);
        }
    }
</style>

</head>
<body>
<div class="container">
<div class="waterfall" id="waterfall"></div>
</div>

<script>
    class Waterfall {
        constructor(container) {
            this.container = container;
            this.items = [];
            this.columns = 4;
            this.gap = 20;
            this.init();
        }

        init() {
            this.createItems();
            this.layout();
            window.addEventListener('resize', () => this.layout());
        }

        createItems() {
            // 模拟数据
            const data = [
                { title: '图片1', desc: '描述文本1', height: 200 },
                { title: '图片2', desc: '描述文本2', height: 300 },
                { title: '图片3', desc: '描述文本3', height: 250 },
                { title: '图片4', desc: '描述文本4', height: 350 },
                { title: '图片5', desc: '描述文本5', height: 280 },
                { title: '图片6', desc: '描述文本6', height: 320 },
                { title: '图片7', desc: '描述文本7', height: 240 },
                { title: '图片8', desc: '描述文本8', height: 260 },
                { title: '图片9', desc: '描述文本9', height: 290 },
                { title: '图片10', desc: '描述文本10', height: 310 },
            ];

            data.forEach(item => {
                const div = document.createElement('div');
                div.className = 'item';
                div.innerHTML = `
                    <img src="https://picsum.photos/400/${item.height}" alt="${item.title}">
                    <div class="content">
                        <div class="title">${item.title}</div>
                        <div class="desc">${item.desc}</div>
                    </div>
                `;
                this.container.appendChild(div);
                this.items.push(div);
            });
        }

        layout() {
            const containerWidth = this.container.clientWidth;
            const itemWidth = (containerWidth - (this.columns - 1) * this.gap) / this.columns;
            const columnHeights = new Array(this.columns).fill(0);
            const columnItems = new Array(this.columns).fill().map(() => []);

            this.items.forEach(item => {
                // 找到最短的列
                const minHeight = Math.min(...columnHeights);
                const columnIndex = columnHeights.indexOf(minHeight);

                // 设置元素位置
                item.style.width = `${itemWidth}px`;
                item.style.left = `${columnIndex * (itemWidth + this.gap)}px`;
                item.style.top = `${columnHeights[columnIndex]}px`;

                // 更新列高度
                columnHeights[columnIndex] += item.offsetHeight + this.gap;
                columnItems[columnIndex].push(item);
            });

            // 设置容器高度
            this.container.style.height = `${Math.max(...columnHeights)}px`;
        }
    }

    // 初始化瀑布流
    const waterfall = new Waterfall(document.getElementById('waterfall'));
</script>

</body>
</html>
效果展示


屏幕截图 2025-05-06 180542.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • <!DOCTYPE html> 瀑布流布局 * {margin: 0;padding: 0;box-si...
    张伯萱阅读 49评论 0 0
  • 资源下载路径 该资源内置源码以及相关copper.js jq等资源https://download.csdn.ne...
    陈杨_a278阅读 1,065评论 0 0
  • 瀑布流的特点是每个项的宽度一致,高度不同,每次把图片添加到高度最低的一列以降低最后整体的高度差 瀑布流最好的方式是...
    practise贝阅读 761评论 0 0
  • 本文主要讲述页面布局样式方面涉及的知识点,更全面的对CSS相应的技术进行归类、整理、说明,没有特别详细的技术要点说...
    Joel_zh阅读 1,012评论 0 1
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,868评论 1 92