- assets/vendor 全量迁移: fontawesome5→assets/fontawesome5, css→assets/css, js→assets/js/runtime(避开 14 个同名自有文件), img 合并去重→assets/img, fonts→assets/fonts; 删除 assets/vendor - libs 五个与 widgets/third-party 字节相同的库不重复入库, loader paths 改指向 - 运行时切换: _win.uri=assets 根, loader baseUrl=/js/runtime, enlighter 注入 路径同步; PHP 7 个引用文件切换并改名 $zibll_*→$runtime_* - 去品牌: Qinver 头注释/品牌 console.log/演示链接清除, 默认文案中性化 - 功能标识符改名: zib__→aksrt__, zib_ajax→aksrt_ajax, window.zib→ window.aksrtLegacy, zibllblock/*→aksrtblock/*, .zib-widget→.aksrt-panel, .zib-slider→.aksrt-slider, zib_menu_options meta 键等 - 自有 CSS 改名: legacy-utilities/compat-vars/footer shell - admin SPA 重建; 契约测试同步(路径/断言/文件更名) - 例外保留: tests/visual 对照环境与 fixtures 前缀(外部 Zibll 产品引用) 验证: php -l 133 个改动文件通过; runtime 86 个 JS node --check 通过; 契约测试 68/70(2 个失败经 stash 对照确认为存量问题)
109 lines
3.4 KiB
JavaScript
109 lines
3.4 KiB
JavaScript
$.fn.waterfall = function (options) {
|
|
var defaults = {
|
|
hGap: null,
|
|
vGap: null,
|
|
itemSelector: '.waterfall-item',
|
|
containerSelector: '.waterfall-container',
|
|
};
|
|
|
|
var settings = $.extend(defaults, options);
|
|
|
|
this.each(function () {
|
|
var $this = $(this);
|
|
initWaterfall($this);
|
|
|
|
if ($this.data('waterfall-init')) return;
|
|
|
|
$this.data('waterfall-init', true);
|
|
|
|
$(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 = $(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');
|
|
}
|
|
};
|