瀑布流

瀑布流式布局是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。国内大多数清新站基本为这类风格。

优点:

  • 降低了界面复杂度,节省了空间
  • 对于触屏设备更加友好,通过向上滑动浏览
  • 使用户专注于浏览,去掉繁琐的操作,体验更好

原理

瀑布流的元素为等宽元素(不等高),其以列排布,无限加载下去。这其中就涉及一个问题:如何使得每列高度差不多相等。

一个简单的算法是贪心算法:

  1. 各列高度初始化为 0
  2. 寻找各列之中所有元素高度之和的最小者
  3. 将新的元素添加到该列上
  4. 该列高度加上新元素的高度
  5. 如果还有未添加元素,跳转至第 2.

实现

一个完整的实现如下

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

<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .item {
            position: absolute;
            width: 250px;
            margin: 5px;
            transition: all 1s;
        }

        .water-fall {
            position: relative;
        }

        .type1 {
            background-color: Cyan;
            height: 250px;
        }

        .type2 {
            background-color: Coral;
            height: 450px;
        }

        .type3 {
            background-color: Indigo;
            height: 350px;
        }
    </style>
</head>

<body>
    <div class="water-fall">
        <div class="item type1">1</div>
        <div class="item type2">2</div>
        <div class="item type3">3</div>
        <div class="item type2">4</div>
        <div class="item type3">5</div>
        <div class="item type1">6</div>
        <div class="item type2">7</div>
        <div class="item type3">8</div>
        <div class="item type2">9</div>
        <div class="item type3">10</div>
        <div class="item type1">11</div>
        <div class="item type3">12</div>
        <div class="item type1">13</div>
        <div class="item type3">14</div>
        <div class="item type1">15</div>
        <div class="item type2">16</div>
        <div class="item type1">17</div>
        <div class="item type2">18</div>

    </div>
    <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
    <script>
        function findMinIndex(arr) {
            var minIndex = 0;
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] < arr[minIndex])
                    minIndex = i;
            }
            return minIndex;
        }

        function waterFall() {

            var itemWidth = $(".item").outerWidth(true)
            var containerWidth = $(".water-fall").width()
            var colNum = Math.floor(containerWidth / itemWidth);
            var heights = [];

            for (var i = 0; i < colNum; i++) {
                heights.push(0)
            }

            $(".item").each(function () {
                var col = findMinIndex(heights);
                var ele = $(this)

                ele.css({
                    top: heights[col] + "px",
                    left: col * itemWidth + "px"
                });

                heights[col] += ele.outerHeight(true);
            })

        }

        waterFall();

        $(window).on("resize", function () {
            waterFall()
        })
    </script>
</body>

</html>

点击这里预览,请改变浏览器宽度,看看效果

优化

思考:

  • 无限加载怎么实现?
  • 瀑布流有没有必要配合上图片懒加载?
  • 瀑布流元素用 img ,而 img 没有加载的时候瀑布流项的高度无法确定,我们该怎么办?
  • 如何获取数据,动态渲染出瀑布流?

提示:

  • 我们可以绑定 scroll 事件,在瀑布流底部添加一个加载更多的 div,当 div 被用户看到的时候,加载更多内容。或者直接计算文档高度和用户滚动高度只差,小于某个值即加载更多。
  • 没必要,为什么?
  • 响应 img 标签的 load 事件,具体该怎么做那?
  • 跨域获取数据,前端动态渲染

results matching ""

    No results matching ""