const defaultConfig = {
boxName: '#waterfall',
itemName: '.waterfall__item',
gap: 10,
boxLeft: 15
};
module.exports = class Waterfall {
constructor(userConfig) {
const _this = this;
this.config = Object.assign({}, defaultConfig, userConfig);
this.$box = $(this.config.boxName);
this.$items = this.$box.find(this.config.itemName);
this.pageWidth = $(document).width();
this.itemWidth = this.$items.eq(0).outerWidth();
this.gap = (this.pageWidth / 375) * this.config.gap;
this.boxLeft = (this.pageWidth / 375) * this.config.boxLeft;
this.columns = parseInt(this.pageWidth / (this.itemWidth + this.gap), 10);
this.itemHeightArr = [];
for (let i = 0; i < this.$items.length; i++) {
const $curItem = this.$items.eq(i);
const counted = $curItem.data('count');
if (i < this.columns) {
// 2- 确定第一行
if (!counted) {
$curItem.css({
top: 0,
left: (_this.itemWidth + _this.gap) * i + _this.boxLeft + 'px'
});
// 标记当前项被计算过,防止重复计算
$curItem.data('count', true);
}
this.itemHeightArr.push($curItem.outerHeight());
} else {
// eslint-disable-next-line
// 其他行
// 3- 找到数组中最小高度 和 它的索引
this.minHeight = this.itemHeightArr[0];
this.minIndex = 0;
for (let j = 0; j < this.itemHeightArr.length; j++) {
if (this.minHeight > this.itemHeightArr[j]) {
this.minHeight = this.itemHeightArr[j];
this.minIndex = j;
}
}
// 4- 设置下一行的第一个盒子位置
// top值就是最小列的高度 + gap
if (!counted) {
$curItem.css({
top: _this.itemHeightArr[_this.minIndex] + _this.gap + 'px',
left: _this.$items.eq(_this.minIndex).offset().left + 'px'
});
// 标记当前项被计算过,防止重复计算
$curItem.data('count', true);
}
// 5- 修改最小列的高度
// 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
this.itemHeightArr[this.minIndex] =
this.itemHeightArr[this.minIndex] + $curItem.outerHeight() + this.gap;
}
}
}
};