mirror of https://github.com/iAJue/Fantasy-field
146 lines
5.4 KiB
JavaScript
146 lines
5.4 KiB
JavaScript
/**
|
|
* jquery waterfall
|
|
* @author richard chen
|
|
* @update 2014-10-07
|
|
* @version 1.0
|
|
* @parameters
|
|
* itemClass: the brick element class
|
|
* spacingWidth: the brick element horizontal spacing
|
|
* spacingHeight: the brick element vertical spacing
|
|
* minColCount: min columns
|
|
* resizeable: trigger positionAll() when browser window is resized
|
|
* itemAlign: the alignment of the brick element ( e.q. [center|left] )
|
|
* isFadeIn: fadeIn effect on loading
|
|
* ajaxCallback: callback when ajax loaded, two parameters ( success, end )
|
|
*/
|
|
(function($) {
|
|
var $window = $(window),
|
|
pluginName = 'waterfall',
|
|
defaults = {
|
|
itemClass: "waterfall-item", // the brick element class
|
|
spacingWidth: 10, // the brick element horizontal spacing
|
|
spacingHeight: 10, // the brick element vertical spacing
|
|
minColCount: 2, // min columns
|
|
resizeable: false, // trigger positionAll() when browser window is resized
|
|
itemAlign: "center", // the alignment of the brick element ( e.q. [center|left] )
|
|
isFadeIn: true, // fadeIn effect on loading
|
|
ajaxCallback: null // callback when ajax loaded, two parameters ( success, end )
|
|
};
|
|
|
|
function Waterfall(element, options) {
|
|
this.$element = $(element);
|
|
this.options = $.extend(true, {}, defaults, options);
|
|
this.ajaxLoading = false; // is ajax loading
|
|
this.colHeightArray = []; // height of each columns
|
|
|
|
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(
|
|
// reposition all the brick element after successful load ajax data
|
|
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); |