瀑布流原來這麼簡單

hant發表於2019-09-03

1. 簡介

採用jquery的waterfall外掛,下面是waterfall的原始碼,原始碼不多,直接貼出來,新建檔案複製程式碼,既可以使用。

(function ($) {
    var $window = $(window), pluginName = 'waterfall', defaults = {
        itemClass: "waterfall-item",
        spacingWidth: 10,
        spacingHeight: 10,
        minColCount: 2,
        resizeable: false,
        itemAlign: "center",
        isFadeIn: true,
        ajaxCallback: null
    };

    function Waterfall(element, options) {
        this.$element = $(element);
        this.options = $.extend(true, {}, defaults, options);
        this.ajaxLoading = false;
        this.colHeightArray = [];
        this._init();
    }

    Waterfall.prototype = {
        constructor: Waterfall, _init: function () {
            var $this = this;
            $window.on("load", function () {
                $this._positionAll();
            });
            if (this.options.resizeable) {
                $window.on("resize", function () {
                    $this._positionAll();
                });
            }
            this._doScroll();
        }, _getColumnCount: function () {
            var parentWidth = this.$element.width(), $item = $(this.options.itemClass),
                itemWidth = $item.eq(0).outerWidth(),
                iCol = Math.floor(parentWidth / (itemWidth + this.options.spacingWidth)), realWidth = 0, leftOffset = 0;
            iCol = iCol > this.options.minColCount ? iCol : this.options.minColCount;
            realWidth = iCol * itemWidth;
            if (parentWidth > realWidth) {
                leftOffset = Math.floor((parentWidth - realWidth - iCol * this.options.spacingWidth) / 2);
            }
            this.itemWidth = itemWidth;
            this.cols = iCol;
            this.leftOffset = this.options.itemAlign == "center" ? leftOffset : 0;
        }, _positionAll: function () {
            var $this = this, $item = $(this.options.itemClass), minHeight, minIndex;
            this._getColumnCount();
            this.colHeightArray = [];
            $item.each(function (index) {
                $(this).css("position", "absolute");
                if (index < $this.cols) {
                    $(this).css("top", 0);
                    $(this).css("left", $this.leftOffset + index * $this.itemWidth + index * $this.options.spacingWidth);
                    $this.colHeightArray.push($(this).outerHeight());
                } else {
                    minHeight = Math.min.apply(null, $this.colHeightArray);
                    minIndex = $.inArray(minHeight, $this.colHeightArray);
                    $(this).css("top", minHeight + $this.options.spacingHeight);
                    $(this).css("left", $item.eq(minIndex).offset().left);
                    $this.colHeightArray[minIndex] += $(this).outerHeight() + $this.options.spacingHeight;
                }
                if ($this.options.isFadeIn) {
                    $(this).animate({"opacity": 1}, 300);
                }
            });
            this.$element.css("height", Math.max.apply(null, $this.colHeightArray));
        }, _doScroll: function () {
            var $this = this, scrollTimer;
            $window.on("scroll", function () {
                if (scrollTimer) {
                    clearTimeout(scrollTimer);
                }
                scrollTimer = setTimeout(function () {
                    var $last = $($this.options.itemClass).last(), scrollTop = $window.scrollTop() + $window.height();
                    if (!$this.ajaxLoading && scrollTop > $last.offset().top + $last.outerHeight() / 2) {
                        $this.ajaxLoading = true;
                        $this.options.ajaxCallback && $this.options.ajaxCallback(function () {
                            $this._positionAll();
                        }, function () {
                            $this.ajaxLoading = false;
                        });
                    }
                }, 100);
            });
        }
    }
    $.fn[pluginName] = function (options) {
        this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Waterfall(this, options));
            }
        });
        return this;
    }
})(jQuery);

2. 使用方法

定義一個放圖片的div,注意此時的my_container 就是該容器,該容器初始內容一定要超過螢幕高度,不然沒有滾動條,不能觸發載入函式。

  <div class="text-center my_container">
        <div class="box">
            <img src="/imgs/detail/top.jpg">
        </div>

        <div class="box">
            <img src="/upload/pic/2019-09-03/1567491229-gOYDHq5y.jpg">
        </div>

        <div class="box">
            <img src="/upload/pic/2019-09-03/1567491229-gOYDHq5y.jpg">
        </div>
        <div class="box">
            <img src="/upload/pic/2019-09-03/1567491401-YJS4RPt1.jpg">
        </div>
    </div>

引用js檔案和寫js

    <script src="/js/waterfall.js"></script>
    <script type="text/javascript">
        $(".my_container").waterfall({
            itemClass: ".box",  //img 外層的div類名
            minColCount: 1, // 每行最少幾個塊
            spacingHeight: 10, //塊之間的間隔高度
            resizeable: true, //螢幕大小改變時,塊的大小是否可以改變
            ajaxCallback: function (success, end) {// 下拉重新整理時的行數
                var data = {
                    "data": [
                        {"src": "/imgs/detail/introduction_us.jpg"}, {"src": "/imgs/detail/introduction_10.jpg"},
                        {"src": "/imgs/detail/introduction_1.jpg"}, {"src": "/imgs/detail/introduction_5.jpg"},
                        {"src": "/imgs/detail/introduction_3.jpg"}, {"src": "/imgs/detail/introduction_7.jpg"}
                    ]
                }; //data 可以通過ajax請求獲取代替,這裡為了演示,將資料寫死。
                var str = "";
                var templ = '<div class="box" style="opacity:0;filter:alpha(opacity=0);"><div class="pic"><img src="test" /></div></div>';//只是為了方便新增元素寫成這樣,可以直接在 用for迴圈 append()元素。
                for (var i = data.data.length - 1; i > 0; i--) {
                    str += templ.replace("test", data.data[i].src);
                }
                $(".my_container").append(str);
                success();
                end();
            }
        });
    </script>

效果

瀑布流原來這麼簡單

tips 貼一下類樣式

<style>
        .my_container {
            margin: auto;
            position: relative;
        }
        @media screen and (max-width: 768px) {
            .my_container {
                width: 100%;
            }
        }
        .box:hover {
            box-shadow: 0 0 10px #999;
        }
        .box img {
            max-width: 100%;
        }
        .box {
            float: left;
            padding: 10px;
            border: 1px solid #ccc;
            background: #f7f7f7;
            box-shadow: 0 0 8px #ccc;
            width: 500px;
        }
        @media screen and (max-width: 768px){
            .box{
                width: 100%;
            }
        }
    </style>
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章