Put hero main title/subtitle in search before_html (document flow), move the search overlay outside the swiper as a sibling, and reset search/slide-text positioning to zibll tops so title and search no longer overlap.
382 lines
15 KiB
JavaScript
382 lines
15 KiB
JavaScript
/**
|
|
* AKSRT Hero & Swiper Initialization
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
window.AksrtSwipers = { new: [], scroll: [], tab: [] };
|
|
|
|
function initHeroSlider() {
|
|
if (typeof Swiper === "undefined") return;
|
|
|
|
// ===== Type A: .swiper-scroll =====
|
|
document.querySelectorAll(".swiper-scroll:not(.swiper-initialized)").forEach(function (el, index) {
|
|
var c_w = el.offsetWidth;
|
|
var firstSlide = el.querySelector(".swiper-wrapper > *");
|
|
var i_w = firstSlide ? firstSlide.offsetWidth : 200;
|
|
var slidesPerGroup = Math.max(1, Math.floor(c_w / i_w));
|
|
|
|
var option = {
|
|
slidesPerView: "auto",
|
|
freeMode: true,
|
|
freeModeSticky: true,
|
|
mousewheel: { forceToAxis: true },
|
|
slidesPerGroup: slidesPerGroup,
|
|
autoplay: el.dataset.autoplay ? {
|
|
delay: parseInt(el.dataset.interval || "4000", 10),
|
|
disableOnInteraction: false,
|
|
} : false,
|
|
loop: !!el.dataset.loop,
|
|
navigation: {
|
|
nextEl: el.querySelector(".swiper-button-next"),
|
|
prevEl: el.querySelector(".swiper-button-prev"),
|
|
},
|
|
};
|
|
|
|
el.classList.add("swiper-scroll-eq-" + index);
|
|
el.setAttribute("swiper-scroll-index", String(index));
|
|
window.AksrtSwipers.scroll[index] = new Swiper(el, option);
|
|
});
|
|
|
|
// ===== Type B: .swiper-tab =====
|
|
document.querySelectorAll(".swiper-tab:not(.swiper-initialized)").forEach(function (el, index) {
|
|
var speed = parseInt(el.dataset.speed || "0", 10) || Math.floor((el.offsetWidth + 1200) / 170) * 50;
|
|
speed = Math.max(300, speed);
|
|
|
|
var initialSlide = parseInt(el.getAttribute("active-index") || "0", 10);
|
|
|
|
var option = {
|
|
loop: false,
|
|
initialSlide: initialSlide,
|
|
autoHeight: true,
|
|
spaceBetween: 20,
|
|
autoplay: false,
|
|
speed: speed,
|
|
pagination: {
|
|
el: el.querySelector(".swiper-pagination"),
|
|
clickable: true,
|
|
},
|
|
};
|
|
|
|
var tabId = el.getAttribute("swiper-tab");
|
|
if (tabId) {
|
|
var tabNav = document.querySelector('[swiper-tab-nav="' + tabId + '"]');
|
|
if (tabNav && tabNav.swiper) {
|
|
option.thumbs = {
|
|
swiper: tabNav.swiper,
|
|
autoScrollOffset: 2,
|
|
};
|
|
}
|
|
}
|
|
|
|
el.classList.add("swiper-tab-eq-" + index);
|
|
el.setAttribute("swiper-tab-index", String(index));
|
|
window.AksrtSwipers.tab[index] = new Swiper(el, option);
|
|
});
|
|
|
|
// ===== 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);
|
|
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 = Object.prototype.hasOwnProperty.call(jsonConfig, "loop")
|
|
? !!jsonConfig.loop
|
|
: !!el.dataset.loop;
|
|
var parallax = !!el.querySelector("[data-swiper-parallax],[data-swiper-parallax-scale]");
|
|
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 = 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));
|
|
|
|
var swiperArgs = {
|
|
loop: loop,
|
|
autoHeight: autoHeight,
|
|
direction: direction,
|
|
spaceBetween: spaceBetween,
|
|
parallax: parallax,
|
|
effect: effect,
|
|
lazy: { loadPrevNext: true },
|
|
autoplay: autoplay,
|
|
speed: speed,
|
|
pagination: pagination,
|
|
navigation: navigation,
|
|
keyboard: keyboard,
|
|
a11y: { prevSlideMessage: "上一张", nextSlideMessage: "下一张" },
|
|
on: {
|
|
lazyImageReady: function (slideEl, imageEl) {
|
|
if (imageEl) imageEl.classList.add("lazyloaded");
|
|
},
|
|
slideChange: function () {
|
|
el.querySelectorAll(".aksrt-dplayer, video").forEach(function (media) {
|
|
if (media.pause) media.pause();
|
|
var dp = media.closest("[data-dplayer]");
|
|
if (dp && dp._dplayer) dp._dplayer.pause();
|
|
});
|
|
},
|
|
init: function () {
|
|
if (loop) {
|
|
el.querySelectorAll(".swiper-slide-duplicate img").forEach(function (img) {
|
|
img.classList.add("no-imgbox");
|
|
});
|
|
}
|
|
},
|
|
},
|
|
};
|
|
|
|
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";
|
|
swiperArgs.pagination.renderBullet = function (idx, className) {
|
|
var slide = this.slides[idx];
|
|
if (!slide) return "";
|
|
var img = slide.querySelector("img");
|
|
var src = img ? (img.dataset.src || img.src) : "";
|
|
if (src) {
|
|
return '<div class="' + className + '"><img class="aksrt-tilt-thumb" src="' + src + '"></div>';
|
|
}
|
|
return "";
|
|
};
|
|
}
|
|
|
|
var swiperInstance = new Swiper(el, swiperArgs);
|
|
window.AksrtSwipers.new[index] = swiperInstance;
|
|
|
|
if (el.classList.contains("banner-module__swiper")) {
|
|
if (prevBtn) {
|
|
prevBtn.addEventListener("click", function (e) {
|
|
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
|
|
if (swiperInstance && !swiperInstance.destroyed) swiperInstance.slidePrev();
|
|
}, true);
|
|
}
|
|
if (nextBtn) {
|
|
nextBtn.addEventListener("click", function (e) {
|
|
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
|
|
if (swiperInstance && !swiperInstance.destroyed) swiperInstance.slideNext();
|
|
}, true);
|
|
}
|
|
}
|
|
});
|
|
|
|
// ===== Compat: data-swiper-config JSON =====
|
|
document.querySelectorAll("[data-swiper-config]:not(.swiper-initialized):not(.new-swiper):not(.swiper-scroll):not(.swiper-tab)").forEach(function (el) {
|
|
var config = {};
|
|
try { config = JSON.parse(el.dataset.swiperConfig || "{}"); } catch (e) {}
|
|
|
|
var paginationEl = el.querySelector(".swiper-pagination, .header-components__pagination");
|
|
var prevBtn = el.querySelector(".swiper-button-prev");
|
|
var nextBtn = el.querySelector(".swiper-button-next");
|
|
|
|
var defaults = {
|
|
effect: "fade",
|
|
fadeEffect: { crossFade: true },
|
|
loop: true,
|
|
speed: 600,
|
|
autoplay: { delay: 5000, disableOnInteraction: false },
|
|
pagination: paginationEl ? { el: paginationEl, type: "progressbar" } : false,
|
|
navigation: (prevBtn && nextBtn) ? { prevEl: prevBtn, nextEl: nextBtn } : false,
|
|
keyboard: { enabled: true },
|
|
a11y: { prevSlideMessage: "上一张", nextSlideMessage: "下一张" },
|
|
};
|
|
|
|
var finalConfig = Object.assign({}, defaults, config);
|
|
if (config.pagination && typeof config.pagination === "object") {
|
|
if (!config.pagination.el && paginationEl) config.pagination.el = paginationEl;
|
|
finalConfig.pagination = Object.assign({}, defaults.pagination || {}, config.pagination);
|
|
} else if (config.pagination === false) {
|
|
finalConfig.pagination = false;
|
|
}
|
|
if (config.navigation === true && prevBtn && nextBtn) {
|
|
finalConfig.navigation = { prevEl: prevBtn, nextEl: nextBtn };
|
|
}
|
|
|
|
new Swiper(el, finalConfig);
|
|
});
|
|
|
|
// Clickable slides
|
|
document.querySelectorAll(".swiper-slide[data-link]").forEach(function (slide) {
|
|
var link = slide.dataset.link;
|
|
if (link && link !== "#") {
|
|
slide.style.cursor = "pointer";
|
|
slide.addEventListener("click", function (e) {
|
|
if (e.target.closest(".header-components-search, .header-slider-search, .header-components-card, .header-slider-card, .hero__btn, .swiper-button-prev, .swiper-button-next, .swiper-pagination, .hero-search, a, button, input")) return;
|
|
window.location.href = link;
|
|
});
|
|
}
|
|
});
|
|
|
|
// Legacy hero__slides fallback
|
|
document.querySelectorAll(".hero__slides:not(.swiper-wrapper)").forEach(function (slider) {
|
|
var slides = slider.querySelectorAll(".hero__slide");
|
|
var dots = slider.querySelectorAll(".hero__dot");
|
|
var prevBtn = slider.closest("section")?.querySelector(".hero__btn--prev");
|
|
var nextBtn = slider.closest("section")?.querySelector(".hero__btn--next");
|
|
if (!slides.length || slides.length <= 1) return;
|
|
|
|
var autoplayInterval = parseInt(slider.dataset.autoplay || "5000", 10) || 5000;
|
|
var pauseOnHover = slider.dataset.pauseOnHover === "true";
|
|
var current = 0;
|
|
var timer = null;
|
|
var paused = false;
|
|
|
|
function show(index) {
|
|
index = ((index % slides.length) + slides.length) % slides.length;
|
|
slides[current].classList.remove("active");
|
|
if (dots[current]) dots[current].setAttribute("aria-selected", "false");
|
|
current = index;
|
|
slides[current].classList.add("active");
|
|
if (dots[current]) dots[current].setAttribute("aria-selected", "true");
|
|
}
|
|
function next() { show(current + 1); }
|
|
function prev() { show(current - 1); }
|
|
function startAutoplay() { stopAutoplay(); timer = setInterval(next, autoplayInterval); }
|
|
function stopAutoplay() { if (timer) clearInterval(timer); timer = null; }
|
|
function restart() { if (!paused) { stopAutoplay(); startAutoplay(); } }
|
|
|
|
show(0);
|
|
if (nextBtn) nextBtn.addEventListener("click", function () { next(); restart(); });
|
|
if (prevBtn) prevBtn.addEventListener("click", function () { prev(); restart(); });
|
|
dots.forEach(function (dot, i) { dot.addEventListener("click", function () { show(i); restart(); }); });
|
|
|
|
slider.setAttribute("tabindex", "-1");
|
|
slider.addEventListener("keydown", function (e) {
|
|
if (e.key === "ArrowRight") { next(); restart(); }
|
|
else if (e.key === "ArrowLeft") { prev(); restart(); }
|
|
});
|
|
|
|
if (pauseOnHover) {
|
|
slider.addEventListener("mouseenter", function () { paused = true; stopAutoplay(); });
|
|
slider.addEventListener("mouseleave", function () { paused = false; startAutoplay(); });
|
|
}
|
|
|
|
slides.forEach(function (slide) {
|
|
var link = slide.dataset.link;
|
|
if (link && link !== "#") {
|
|
slide.style.cursor = "pointer";
|
|
slide.addEventListener("click", function () { window.location.href = link; });
|
|
}
|
|
});
|
|
|
|
var touchStartX = 0;
|
|
slider.addEventListener("touchstart", function (e) { touchStartX = e.changedTouches[0].screenX; stopAutoplay(); }, { passive: true });
|
|
slider.addEventListener("touchend", function (e) {
|
|
var diff = touchStartX - e.changedTouches[0].screenX;
|
|
if (Math.abs(diff) > 50) { if (diff > 0) next(); else prev(); }
|
|
startAutoplay();
|
|
}, { passive: true });
|
|
|
|
startAutoplay();
|
|
document.addEventListener("visibilitychange", function () {
|
|
if (document.hidden) stopAutoplay();
|
|
else if (!paused) startAutoplay();
|
|
});
|
|
});
|
|
}
|
|
|
|
window.AksrtFrontend.register("aksrt-hero-slider", function () { initHeroSlider(); });
|
|
})(); |