前言
轮播图是网站中常见的组件,用于展示多张图片或内容。本文将介绍如何实现一个无缝轮播图,包括其核心原理和具体实现。
实现原理
无缝轮播图的核心原理是通过克隆首尾元素,在视觉上实现无限循环的效果。具体来说:
- 克隆第一个元素并添加到末尾
- 克隆最后一个元素并添加到开头
- 当滑动到克隆元素时,通过无动画的方式跳转到真实元素
- 使用 CSS transform 和 transition 实现平滑过渡
代码实现
HTML 结构
html
<div class="carousel-container">
<div class="carousel-wrapper">
<div class="carousel-item">1</div>
<div class="carousel-item">2</div>
<div class="carousel-item">3</div>
<div class="carousel-item">4</div>
</div>
<div class="carousel-controls">
<button class="carousel-button prev">❮</button>
<button class="carousel-button next">❯</button>
</div>
<div class="carousel-indicators">
<span class="carousel-indicator active"></span>
<span class="carousel-indicator"></span>
<span class="carousel-indicator"></span>
<span class="carousel-indicator"></span>
</div>
</div>
CSS 样式
css
.carousel-container {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
}
.carousel-wrapper {
display: flex;
height: 100%;
transition: transform 0.5s ease-in-out;
}
.carousel-item {
flex: 0 0 100%;
height: 100%;
}
TypeScript 实现
typescript
class Carousel {
private container: HTMLElement;
private items: HTMLElement[];
private currentIndex: number = 0;
private timer: number | null = null;
private isTransitioning: boolean = false;
constructor(selector: string) {
this.container = document.querySelector(selector) as HTMLElement;
this.items = Array.from(this.container.children) as HTMLElement[];
this.init();
}
private init(): void {
// 克隆首尾元素
const firstClone = this.items[0].cloneNode(true) as HTMLElement;
const lastClone = this.items[this.items.length - 1].cloneNode(true) as HTMLElement;
this.container.insertBefore(lastClone, this.items[0]);
this.container.appendChild(firstClone);
this.items = Array.from(this.container.children) as HTMLElement[];
this.currentIndex = 1;
this.updatePosition();
// 添加事件监听
this.container.addEventListener('transitionend', this.handleTransitionEnd.bind(this));
this.container.addEventListener('mouseenter', this.pause.bind(this));
this.container.addEventListener('mouseleave', this.start.bind(this));
this.start();
}
}
核心功能实现
1. 自动播放
通过 setInterval
实现自动播放,并在鼠标悬停时暂停:
typescript
public start(): void {
if (this.timer) return;
this.timer = window.setInterval(() => {
this.next();
}, 3000);
}
public pause(): void {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}
2. 无缝切换
通过克隆元素和位置重置实现无缝切换:
typescript
private handleTransitionEnd(): void {
this.isTransitioning = false;
if (this.currentIndex === 0) {
this.currentIndex = this.items.length - 2;
} else if (this.currentIndex === this.items.length - 1) {
this.currentIndex = 1;
}
this.container.style.transition = 'none';
this.updatePosition();
this.container.offsetHeight;
this.container.style.transition = 'transform 0.5s ease-in-out';
}
3. 指示器联动
通过监听指示器点击事件实现跳转:
typescript
const indicators = document.querySelectorAll('.carousel-indicator');
indicators.forEach((indicator, index) => {
indicator.addEventListener('click', () => {
const currentIndex = carousel.currentIndex;
const targetIndex = index + 1;
if (targetIndex > currentIndex) {
for (let i = currentIndex; i < targetIndex; i++) {
carousel.next();
}
} else if (targetIndex < currentIndex) {
for (let i = currentIndex; i > targetIndex; i--) {
carousel.prev();
}
}
});
});