Files
wordpress-theme-aksrt/assets/js/runtime/waterfall.js
T
2026-08-25 20:15:55 +08:00

109 lines
3.4 KiB
JavaScript

jQuery.fn.waterfall = function (options) {
var defaults = {
hGap: null,
vGap: null,
itemSelector: '.waterfall-item',
containerSelector: '.waterfall-container',
};
var settings = jQuery.extend(defaults, options);
this.each(function () {
var $this = jQuery(this);
initWaterfall($this);
if ($this.data('waterfall-init')) return;
$this.data('waterfall-init', true);
jQuery(window).on(
'resize',
debounce(function () {
initWaterfall($this);
}, 100)
);
$this.on(
'lazyloaded',
'img',
debounce(function () {
initWaterfall($this);
}, 50)
);
$this.on('post_ajax.ed', function () {
initWaterfall($this);
});
});
function getGap(container) {
var horizontalGap = settings.hGap;
var verticalGap = settings.vGap;
var items = container.find(settings.itemSelector);
if (items.length && horizontalGap === null) {
horizontalGap = parseInt(container.data('h-gap')); // 水平间距
if (!horizontalGap) {
horizontalGap = parseInt(items.eq(0).css('margin-left')) + parseInt(items.eq(0).css('margin-right'));
}
}
if (items.length && verticalGap === null) {
verticalGap = parseInt(container.data('v-gap')); // 垂直间距
if (!verticalGap) {
verticalGap = parseInt(items.eq(0).css('margin-top')) + parseInt(items.eq(0).css('margin-bottom'));
}
}
return { horizontalGap: horizontalGap, verticalGap: verticalGap };
}
//瀑布流布局
function initWaterfall(container) {
if (!container.length) return;
var items = container.find(settings.itemSelector);
if (!items.length) return;
//获取列数和间距
const containerWidth = container.width();
const itemWidth = items.eq(0).outerWidth();
const columns = Math.floor(containerWidth / itemWidth);
const { horizontalGap, verticalGap } = getGap(container);
//计算第一个项目距离容器顶部的位置,减去自身margin-top
const firstItemTop = items.eq(0).offset().top - container.offset().top - parseInt(items.eq(0).css('margin-top'));
//初始化列高度数组
let colHeights = new Array(columns).fill(firstItemTop);
//遍历所有子项目
items.each(function () {
const $item = jQuery(this);
//找到最短的列
const minHeight = Math.min(...colHeights);
const minCol = colHeights.indexOf(minHeight);
//计算位置,加入间距
const left = minCol * itemWidth + horizontalGap * minCol;
const top = minHeight + (minHeight > 0 ? verticalGap : 0);
//设置位置
$item
.css({
position: 'absolute',
left: '0',
top: '0',
transform: 'translate3d(' + left + 'px,' + top + 'px,0)',
})
.addClass('waterfall-item');
//更新列高度
colHeights[minCol] += $item.height() + verticalGap;
});
//设置容器高度,考虑底部间距
container.css('height', Math.max(...colHeights) + verticalGap + 'px');
}
};