/** * Simple Carousel Plugin - Swiper替代方案 * 轻量级轮播插件,避免与平滑滚动库冲突 */ (function() { 'use strict'; class SimpleCarousel { constructor(container, options = {}) { this.container = container; this.options = { autoplay: true, autoplayDelay: 5000, loop: false, navigation: true, pagination: true, touchEnabled: true, ...options }; this.currentIndex = 0; this.slides = []; this.isAnimating = false; this.autoplayTimer = null; this.touchStartX = 0; this.touchEndX = 0; this.init(); } init() { this.setupSlides(); this.setupNavigation(); this.setupPagination(); this.setupTouch(); this.setupAutoplay(); this.updateSlides(); // 触发初始化完成回调 if (this.options.onInit) { this.options.onInit(); } } setupSlides() { const wrapper = this.container.querySelector('.carousel-wrapper'); if (!wrapper) return; this.wrapper = wrapper; // 保存wrapper引用 this.slides = Array.from(wrapper.children); this.slidesPerView = this.options.slidesPerView || 5; this.totalGroups = Math.ceil(this.slides.length / this.slidesPerView); // 设置轮播容器样式 wrapper.style.position = 'relative'; wrapper.style.overflow = 'hidden'; wrapper.style.display = 'flex'; wrapper.style.alignItems = 'center'; wrapper.style.transition = 'transform 0.5s ease'; // 为每个幻灯片设置样式 this.slides.forEach((slide, index) => { if (this.slidesPerView === 1) { // 单个幻灯片模式:每个幻灯片占100%宽度 slide.style.flex = '0 0 100%'; } else { // 多个幻灯片模式:根据slidesPerView计算宽度 const slideWidth = 100 / this.slidesPerView; slide.style.flex = `0 0 ${slideWidth}%`; } slide.style.transition = 'all 0.3s ease'; }); // 初始化显示第一组 this.updateSlides(); } setupNavigation() { if (!this.options.navigation) return; const nextBtn = this.container.querySelector('.carousel-button-next'); const prevBtn = this.container.querySelector('.carousel-button-prev'); if (nextBtn) { nextBtn.addEventListener('click', (e) => { e.preventDefault(); this.next(); }); } if (prevBtn) { prevBtn.addEventListener('click', (e) => { e.preventDefault(); this.prev(); }); } } setupPagination() { if (!this.options.pagination) return; const pagination = this.container.querySelector('.carousel-pagination'); if (!pagination) return; // 使用现有的分页器按钮,只需要绑定事件 const bullets = pagination.querySelectorAll('.carousel-pagination-bullet'); bullets.forEach((bullet, index) => { bullet.addEventListener('click', () => this.goTo(index)); }); } setupTouch() { if (!this.options.touchEnabled) return; const wrapper = this.container.querySelector('.carousel-wrapper'); if (!wrapper) return; wrapper.addEventListener('touchstart', (e) => { this.touchStartX = e.touches[0].clientX; this.pauseAutoplay(); }, { passive: true }); wrapper.addEventListener('touchend', (e) => { this.touchEndX = e.changedTouches[0].clientX; this.handleSwipe(); this.resumeAutoplay(); }, { passive: true }); } setupAutoplay() { if (!this.options.autoplay) return; this.autoplayTimer = setInterval(() => { this.next(); }, this.options.autoplayDelay); } handleSwipe() { const swipeThreshold = 50; const diff = this.touchStartX - this.touchEndX; if (Math.abs(diff) > swipeThreshold) { if (diff > 0) { this.next(); } else { this.prev(); } } } next() { if (this.isAnimating) return; if (this.slidesPerView === 1) { // 单个幻灯片模式:直接切换到下一个 let nextIndex = this.currentIndex + 1; if (nextIndex >= this.slides.length) { nextIndex = this.options.loop ? 0 : this.currentIndex; } if (nextIndex !== this.currentIndex) { this.goTo(nextIndex); } } else { // 多个幻灯片模式:按组切换 const currentGroup = Math.floor(this.currentIndex / this.slidesPerView); let nextGroup = currentGroup + 1; if (nextGroup >= this.totalGroups) { nextGroup = this.options.loop ? 0 : currentGroup; } const nextIndex = nextGroup * this.slidesPerView; if (nextIndex !== this.currentIndex) { this.goTo(nextIndex); } } } prev() { if (this.isAnimating) return; if (this.slidesPerView === 1) { // 单个幻灯片模式:直接切换到上一个 let prevIndex = this.currentIndex - 1; if (prevIndex < 0) { prevIndex = this.options.loop ? this.slides.length - 1 : this.currentIndex; } if (prevIndex !== this.currentIndex) { this.goTo(prevIndex); } } else { // 多个幻灯片模式:按组切换 const currentGroup = Math.floor(this.currentIndex / this.slidesPerView); let prevGroup = currentGroup - 1; if (prevGroup < 0) { prevGroup = this.options.loop ? this.totalGroups - 1 : currentGroup; } const prevIndex = prevGroup * this.slidesPerView; if (prevIndex !== this.currentIndex) { this.goTo(prevIndex); } } } goTo(index) { console.log('SimpleCarousel: goTo 被调用,目标索引:', index, '当前索引:', this.currentIndex); if (this.isAnimating || index === this.currentIndex || index < 0 || index >= this.slides.length) { console.log('SimpleCarousel: goTo 被阻止 - 动画中:', this.isAnimating, '相同索引:', index === this.currentIndex, '索引范围:', index < 0 || index >= this.slides.length); return; } this.isAnimating = true; const previousIndex = this.currentIndex; this.currentIndex = index; console.log('SimpleCarousel: 切换从索引', previousIndex, '到', this.currentIndex); // 更新幻灯片 this.updateSlides(); // 触发回调 if (this.options.onSlideChange) { console.log('SimpleCarousel: 触发 onSlideChange 回调'); this.options.onSlideChange(this.currentIndex, previousIndex); } setTimeout(() => { this.isAnimating = false; }, 500); } updateSlides() { let translateX; if (this.slidesPerView === 1) { // 单个幻灯片模式:直接按索引移动 translateX = -this.currentIndex * 100; } else { // 多个幻灯片模式:按组移动 const currentGroup = Math.floor(this.currentIndex / this.slidesPerView); translateX = -currentGroup * 100; } // 移动整个轮播容器 this.wrapper.style.transform = `translateX(${translateX}%)`; // 更新分页器(如果存在) const bullets = this.container.querySelectorAll('.carousel-pagination-bullet'); bullets.forEach((bullet, index) => { if (this.slidesPerView === 1) { // 单个幻灯片模式:直接按索引激活 bullet.classList.toggle('active', index === this.currentIndex); } else { // 多个幻灯片模式:激活当前可见范围内的幻灯片 const currentGroup = Math.floor(this.currentIndex / this.slidesPerView); const slideGroup = Math.floor(index / this.slidesPerView); bullet.classList.toggle('active', slideGroup === currentGroup); } }); } pauseAutoplay() { if (this.autoplayTimer) { clearInterval(this.autoplayTimer); this.autoplayTimer = null; } } resumeAutoplay() { if (this.options.autoplay && !this.autoplayTimer) { this.autoplayTimer = setInterval(() => { this.next(); }, this.options.autoplayDelay); } } destroy() { this.pauseAutoplay(); // 移除事件监听器 const nextBtn = this.container.querySelector('.carousel-button-next'); const prevBtn = this.container.querySelector('.carousel-button-prev'); const bullets = this.container.querySelectorAll('.carousel-pagination-bullet'); if (nextBtn) nextBtn.replaceWith(nextBtn.cloneNode(true)); if (prevBtn) prevBtn.replaceWith(prevBtn.cloneNode(true)); bullets.forEach(bullet => bullet.replaceWith(bullet.cloneNode(true))); } // 获取当前索引 get activeIndex() { return this.currentIndex; } // 获取幻灯片总数 get slidesLength() { return this.slides.length; } // 销毁实例 destroy() { // 停止自动播放 this.pauseAutoplay(); // 清除事件监听器 this.removeEventListeners(); // 重置样式 if (this.wrapper) { this.wrapper.style.transform = ''; } // 清除引用 this.container = null; this.wrapper = null; this.slides = []; this.autoplayTimer = null; } } // 导出到全局 window.SimpleCarousel = SimpleCarousel; })();