update 4page
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* Home hero carousel — autoplay + dot navigation + mobile swipe
|
||||
*/
|
||||
(function () {
|
||||
var AUTOPLAY_MS = 5000;
|
||||
var SWIPE_THRESHOLD = 48;
|
||||
var MOBILE_MQ = '(max-width: 991.98px)';
|
||||
|
||||
function initHomeHeroCarousel(root) {
|
||||
if (root.getAttribute('data-carousel-ready') === 'true') return;
|
||||
root.setAttribute('data-carousel-ready', 'true');
|
||||
|
||||
var slides = root.querySelectorAll('[data-home-hero-slide]');
|
||||
var dots = root.querySelectorAll('[data-home-hero-dot]');
|
||||
var viewport = root.querySelector('.home-hero-carousel__viewport');
|
||||
if (!slides.length) return;
|
||||
|
||||
var index = 0;
|
||||
var timer = null;
|
||||
var touchStartX = 0;
|
||||
var touchStartY = 0;
|
||||
var touchTracking = false;
|
||||
|
||||
function setSlide(nextIndex) {
|
||||
index = (nextIndex + slides.length) % slides.length;
|
||||
|
||||
slides.forEach(function (slide, i) {
|
||||
var active = i === index;
|
||||
slide.classList.toggle('is-active', active);
|
||||
slide.setAttribute('aria-hidden', active ? 'false' : 'true');
|
||||
});
|
||||
|
||||
dots.forEach(function (dot, i) {
|
||||
var active = i === index;
|
||||
dot.classList.toggle('is-active', active);
|
||||
dot.setAttribute('aria-selected', active ? 'true' : 'false');
|
||||
});
|
||||
}
|
||||
|
||||
function startAutoplay() {
|
||||
stopAutoplay();
|
||||
timer = window.setInterval(function () {
|
||||
setSlide(index + 1);
|
||||
}, AUTOPLAY_MS);
|
||||
}
|
||||
|
||||
function stopAutoplay() {
|
||||
if (timer) {
|
||||
window.clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function isMobileSwipeEnabled() {
|
||||
return window.matchMedia(MOBILE_MQ).matches;
|
||||
}
|
||||
|
||||
function bindTouchSwipe() {
|
||||
if (!viewport || viewport.getAttribute('data-swipe-ready') === 'true') return;
|
||||
viewport.setAttribute('data-swipe-ready', 'true');
|
||||
|
||||
viewport.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
if (!isMobileSwipeEnabled() || !e.touches.length) return;
|
||||
touchStartX = e.touches[0].clientX;
|
||||
touchStartY = e.touches[0].clientY;
|
||||
touchTracking = true;
|
||||
stopAutoplay();
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
|
||||
viewport.addEventListener(
|
||||
'touchend',
|
||||
function (e) {
|
||||
if (!touchTracking) return;
|
||||
touchTracking = false;
|
||||
|
||||
if (!isMobileSwipeEnabled()) {
|
||||
startAutoplay();
|
||||
return;
|
||||
}
|
||||
|
||||
var touch = e.changedTouches[0];
|
||||
if (!touch) {
|
||||
startAutoplay();
|
||||
return;
|
||||
}
|
||||
|
||||
var dx = touch.clientX - touchStartX;
|
||||
var dy = touch.clientY - touchStartY;
|
||||
|
||||
if (Math.abs(dx) < SWIPE_THRESHOLD || Math.abs(dx) <= Math.abs(dy)) {
|
||||
startAutoplay();
|
||||
return;
|
||||
}
|
||||
|
||||
if (dx < 0) {
|
||||
setSlide(index + 1);
|
||||
} else {
|
||||
setSlide(index - 1);
|
||||
}
|
||||
startAutoplay();
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
|
||||
viewport.addEventListener(
|
||||
'touchcancel',
|
||||
function () {
|
||||
touchTracking = false;
|
||||
startAutoplay();
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
}
|
||||
|
||||
dots.forEach(function (dot) {
|
||||
dot.addEventListener('click', function () {
|
||||
var target = Number(dot.getAttribute('data-home-hero-dot'));
|
||||
if (Number.isNaN(target)) return;
|
||||
setSlide(target);
|
||||
startAutoplay();
|
||||
});
|
||||
});
|
||||
|
||||
root.addEventListener('mouseenter', stopAutoplay);
|
||||
root.addEventListener('mouseleave', startAutoplay);
|
||||
root.addEventListener('focusin', stopAutoplay);
|
||||
root.addEventListener('focusout', function (e) {
|
||||
if (!root.contains(e.relatedTarget)) startAutoplay();
|
||||
});
|
||||
|
||||
bindTouchSwipe();
|
||||
setSlide(0);
|
||||
startAutoplay();
|
||||
}
|
||||
|
||||
function boot() {
|
||||
document.querySelectorAll('[data-home-hero-carousel]').forEach(initHomeHeroCarousel);
|
||||
}
|
||||
|
||||
window.AifoHomeHeroCarouselInit = initHomeHeroCarousel;
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', boot);
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
|
||||
document.addEventListener('aifo:home-hero-carousel-reload', boot);
|
||||
})();
|
||||
Reference in New Issue
Block a user