Masonry实现瀑布流+JS加载更多

301 阅读1分钟

效果

  • 瀑布流展示默认子元素

masonry.png

  • 点击加载更多后

masonry1.png

过程

1、导入masonry库,官网

<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>

2、绑定页面父元素和子元素

var parent = document.querySelector('.media-container');
    var msnry = new Masonry(elem, {
    itemSelector: '.media-item',
});

3、页面元素的排布:

  • 父元素包含默认要显示的子元素
  • 其他子元素放到父元素外(很重要!!!不这样做会导致masonry计算出bug)

4、完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Masonry Layout Example</title>
    <style>
        .grid {
            margin: 0 auto;
            position: relative;
        }

        .item {
            width: 30%;
            margin-bottom: 10px;
            margin-right: 10px;
            background-color: #ddd;
            padding: 20px;
            box-sizing: border-box;
        }

        .view-more {
            margin-top: 20px;
            text-align: center;
        }

        .view-more button {
            padding: 10px 20px;
            cursor: pointer;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
        }

        .hidden-item {
            display: none;
        }

        /* 模拟不同高度的子元素 */
        .item:nth-child(odd) {
            height: 150px;
        }

        .item:nth-child(even) {
            height: 250px;
        }

        .item:nth-child(3n) {
            height: 100px;
        }
    </style>
</head>

<body>
    <!-- Masonry 容器 -->
    <div class="parent">
        <!-- 默认显示的元素 -->
        <div class="item">Item 1</div>
        <div class="item">Item 2</div>
        <div class="item">Item 3</div>
        <div class="item">Item 4</div>
        <div class="item">Item 5</div>
        <div class="item">Item 6</div>
        <div class="item">Item 7</div>
        <div class="item">Item 8</div>
    </div>

    <!-- “加载更多”按钮 -->
    <div class="view-more">
        <button id="load-more">加载更多</button>
    </div>

    <!-- 隐藏起来的其他子元素 -->
    <div class="item hidden-item">Item 9</div>
    <div class="item hidden-item">Item 10</div>
    <div class="item hidden-item">Item 11</div>
    <div class="item hidden-item">Item 12</div>
    <div class="item hidden-item">Item 13</div>
    <div class="item hidden-item">Item 14</div>
    <div class="item hidden-item">Item 15</div>
    <div class="item hidden-item">Item 16</div>
    <div class="item hidden-item">Item 17</div>

    <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const parent = document.querySelector('.parent'); // 父元素
            const loadMoreButton = document.getElementById('load-more'); // 按钮
            const hiddenItems = document.querySelectorAll('.item.hidden-item'); // 隐藏起来的其他子元素
            let currentIndex = 0;
            const loadCount = 4;

            // 初始化 Masonry 布局
            const msnry = new Masonry(parent, {
                itemSelector: '.item',
                percentPosition: true
            });
            msnry.layout();
            // 点击“加载更多”按钮事件
            loadMoreButton.addEventListener('click', function () {
                const newItems = [];
                // 加载接下来的 4 个元素
                for (let i = currentIndex; i < currentIndex + loadCount; i++) {
                    if (i >= hiddenItems.length) {
                        this.style.display = 'none';  // 如果没有更多元素,隐藏按钮
                        break;
                    }
                    const item = hiddenItems[i];
                    item.classList.contains('hidden-item') ? item.classList.remove('hidden-item') : false
                    item.style.display = 'block';  // 让元素可见
                    parent.appendChild(item);
                    newItems.push(item);
                }
                currentIndex += loadCount;
                // 添加新元素到 Masonry 并重新布局
                msnry.appended(newItems);
                msnry.layout();
            });
        });
    </script>
</body>

</html>