Files
class-theme/assets/js/carousel.js
2026-02-07 22:27:31 +08:00

79 lines
2.3 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
const carousel = document.querySelector('.js-carousel');
if (!carousel) return;
const track = carousel.querySelector('.js-carousel-track');
const slides = track.children;
const dots = carousel.querySelectorAll('.js-dot');
const prevBtn = carousel.querySelector('.js-carousel-prev');
const nextBtn = carousel.querySelector('.js-carousel-next');
let current = 0;
const total = slides.length;
let touchStartX = 0;
let touchEndX = 0;
function updateDisplay() {
// 移动轨道
track.style.transform = `translateX(-${current * 100}%)`;
// 更新指示器
dots.forEach((dot, i) => {
if (i === current) {
dot.classList.add('bg-white', 'w-6');
dot.classList.remove('bg-white/50');
} else {
dot.classList.remove('bg-white', 'w-6');
dot.classList.add('bg-white/50');
}
});
}
function next() {
current = (current === total - 1) ? 0 : current + 1;
updateDisplay();
}
function prev() {
current = (current === 0) ? total - 1 : current - 1;
updateDisplay();
}
// 自动轮播
let autoPlay = setInterval(next, 5000);
function resetTimer() {
clearInterval(autoPlay);
autoPlay = setInterval(next, 5000);
}
// 事件监听
if (nextBtn) nextBtn.addEventListener('click', () => { next(); resetTimer(); });
if (prevBtn) prevBtn.addEventListener('click', () => { prev(); resetTimer(); });
dots.forEach(dot => {
dot.addEventListener('click', () => {
current = parseInt(dot.getAttribute('data-index'));
updateDisplay();
resetTimer();
});
});
// --- 触摸滑动逻辑 ---
carousel.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
}, { passive: true });
carousel.addEventListener('touchend', (e) => {
touchEndX = e.changedTouches[0].screenX;
const distance = touchStartX - touchEndX;
const minSwipeDistance = 50;
if (Math.abs(distance) > minSwipeDistance) {
if (distance > 0) next(); else prev();
resetTimer();
}
}, { passive: true });
// 初始化
updateDisplay();
});