fix(frontend): restore banner carousel visible height

Global border-box collapsed the banner's height:0 + padding-bottom
aspect box to zero, so slides rendered but took no space. Prefer
aspect-ratio (with content-box fallback) and make .new-swiper honor
data-swiper-config so autoplay/loop/navigation from templates apply.
This commit is contained in:
2026-07-14 23:26:03 +08:00
parent 41e4719621
commit 666560a49a
3 changed files with 155 additions and 30 deletions
+109 -22
View File
@@ -75,24 +75,111 @@
});
// ===== Type C: .new-swiper =====
// Prefer data-swiper-config JSON (used by hero/banner templates), then data-* attrs.
document.querySelectorAll(".new-swiper:not(.swiper-initialized)").forEach(function (el, index) {
var jsonConfig = null;
if (el.dataset.swiperConfig) {
try {
jsonConfig = JSON.parse(el.dataset.swiperConfig);
} catch (e) {
jsonConfig = null;
}
}
if (!jsonConfig || typeof jsonConfig !== "object") {
jsonConfig = {};
}
var delay = parseInt(el.dataset.interval || "6000", 10);
var autoplay = el.dataset.autoplay !== undefined ? {
delay: delay,
disableOnInteraction: false,
} : false;
if (jsonConfig.autoplay && typeof jsonConfig.autoplay === "object" && jsonConfig.autoplay.delay) {
delay = parseInt(jsonConfig.autoplay.delay, 10) || delay;
}
var autoplay;
if (Object.prototype.hasOwnProperty.call(jsonConfig, "autoplay")) {
autoplay = jsonConfig.autoplay;
} else if (el.dataset.autoplay !== undefined) {
autoplay = {
delay: delay,
disableOnInteraction: false,
};
} else {
autoplay = false;
}
var speed = parseInt(el.dataset.speed || "0", 10) || Math.floor((el.offsetWidth + 1000) / 22) * 10;
if (jsonConfig.speed) {
speed = parseInt(jsonConfig.speed, 10) || speed;
}
speed = Math.max(400, speed);
if (!autoplay) speed = Math.floor(speed / 1.6);
var loop = !!el.dataset.loop;
var loop = Object.prototype.hasOwnProperty.call(jsonConfig, "loop")
? !!jsonConfig.loop
: !!el.dataset.loop;
var parallax = !!el.querySelector("[data-swiper-parallax],[data-swiper-parallax-scale]");
var effect = el.dataset.effect || "slide";
var direction = el.dataset.direction || "horizontal";
var spaceBetween = parseInt(el.dataset.spaceBetween || "0", 10);
var effect = jsonConfig.effect || el.dataset.effect || "slide";
var direction = jsonConfig.direction || el.dataset.direction || "horizontal";
var spaceBetween = Object.prototype.hasOwnProperty.call(jsonConfig, "spaceBetween")
? parseInt(jsonConfig.spaceBetween, 10) || 0
: parseInt(el.dataset.spaceBetween || "0", 10);
var paginationType = el.dataset.paginationType || "bullets";
var autoHeight = el.hasAttribute("auto-height");
var autoHeight = Object.prototype.hasOwnProperty.call(jsonConfig, "autoHeight")
? !!jsonConfig.autoHeight
: el.hasAttribute("auto-height");
// Fixed-ratio modules (banner card) must not use autoHeight — it collapses absolute slides.
if (el.classList.contains("banner-module__swiper") || el.classList.contains("scale-height")) {
autoHeight = false;
}
var paginationEl = el.querySelector(".swiper-pagination, .header-components__pagination");
var prevBtn = el.querySelector(".swiper-button-prev, .banner-module__prev");
var nextBtn = el.querySelector(".swiper-button-next, .banner-module__next");
var pagination = false;
if (Object.prototype.hasOwnProperty.call(jsonConfig, "pagination")) {
if (jsonConfig.pagination === false) {
pagination = false;
} else if (jsonConfig.pagination && typeof jsonConfig.pagination === "object") {
pagination = Object.assign(
{
el: paginationEl,
clickable: true,
},
jsonConfig.pagination
);
if (!pagination.el) pagination.el = paginationEl;
if (!pagination.el) pagination = false;
} else if (jsonConfig.pagination) {
pagination = paginationEl
? { el: paginationEl, type: paginationType, clickable: true }
: false;
}
} else {
pagination = paginationEl
? { el: paginationEl, type: paginationType, clickable: true }
: false;
}
var navigation = false;
if (Object.prototype.hasOwnProperty.call(jsonConfig, "navigation")) {
if (jsonConfig.navigation === false) {
navigation = false;
} else if (jsonConfig.navigation === true || jsonConfig.navigation) {
navigation = prevBtn && nextBtn
? { nextEl: nextBtn, prevEl: prevBtn }
: false;
}
} else {
navigation = {
nextEl: nextBtn,
prevEl: prevBtn,
};
}
var keyboard = Object.prototype.hasOwnProperty.call(jsonConfig, "keyboard")
? jsonConfig.keyboard
: { enabled: true };
el.classList.add("swiper-new-eq-" + index);
el.setAttribute("swiper-new-index", String(index));
@@ -107,16 +194,9 @@
lazy: { loadPrevNext: true },
autoplay: autoplay,
speed: speed,
pagination: {
el: el.querySelector(".swiper-pagination"),
type: paginationType,
clickable: true,
},
navigation: {
nextEl: el.querySelector(".swiper-button-next"),
prevEl: el.querySelector(".swiper-button-prev"),
},
keyboard: { enabled: true },
pagination: pagination,
navigation: navigation,
keyboard: keyboard,
a11y: { prevSlideMessage: "上一张", nextSlideMessage: "下一张" },
on: {
lazyImageReady: function (slideEl, imageEl) {
@@ -139,7 +219,16 @@
},
};
if (paginationType === "thumbnail") {
if (effect === "fade") {
swiperArgs.fadeEffect = Object.assign(
{ crossFade: true },
(jsonConfig.fadeEffect && typeof jsonConfig.fadeEffect === "object")
? jsonConfig.fadeEffect
: {}
);
}
if (pagination && paginationType === "thumbnail") {
swiperArgs.pagination.type = "bullets";
swiperArgs.pagination.bulletClass = "pagination-thumbnail-item";
swiperArgs.pagination.bulletActiveClass = "pagination-thumbnail-item-active";
@@ -159,8 +248,6 @@
window.AksrtSwipers.new[index] = swiperInstance;
if (el.classList.contains("banner-module__swiper")) {
var prevBtn = el.querySelector(".swiper-button-prev");
var nextBtn = el.querySelector(".swiper-button-next");
if (prevBtn) {
prevBtn.addEventListener("click", function (e) {
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();