js实现轮播海报
实现轮播海报的基本思路
轮播海报通常通过定时切换图片或内容实现动态展示效果。核心逻辑包括:图片切换、动画过渡、定时器控制以及用户交互(如手动切换)。
HTML 结构
基础HTML结构包含一个容器包裹多个轮播项(图片或其他内容),以及导航按钮或指示器:
<div class="slider-container">
<div class="slider-wrapper">
<div class="slider-item">内容1</div>
<div class="slider-item">内容2</div>
<div class="slider-item">内容3</div>
</div>
<!-- 导航按钮 -->
<button class="prev-btn">上一张</button>
<button class="next-btn">下一张</button>
<!-- 指示器 -->
<div class="indicator"></div>
</div>
CSS 样式
通过CSS设置轮播项的布局和过渡效果:
.slider-container {
position: relative;
overflow: hidden;
width: 100%;
}
.slider-wrapper {
display: flex;
transition: transform 0.5s ease;
}
.slider-item {
min-width: 100%;
height: 300px;
}
.prev-btn, .next-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 10;
}
.prev-btn { left: 10px; }
.next-btn { right: 10px; }
JavaScript 核心逻辑
通过操作DOM和定时器实现自动轮播:
document.addEventListener('DOMContentLoaded', function() {
const sliderWrapper = document.querySelector('.slider-wrapper');
const sliderItems = document.querySelectorAll('.slider-item');
const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
const indicator = document.querySelector('.indicator');
let currentIndex = 0;
const totalItems = sliderItems.length;
// 初始化指示器
function initIndicator() {
for (let i = 0; i < totalItems; i++) {
const dot = document.createElement('span');
dot.classList.add('dot');
if (i === 0) dot.classList.add('active');
dot.addEventListener('click', () => goToIndex(i));
indicator.appendChild(dot);
}
}
// 切换至指定索引
function goToIndex(index) {
currentIndex = (index + totalItems) % totalItems;
sliderWrapper.style.transform = `translateX(-${currentIndex * 100}%)`;
updateIndicator();
}
// 更新指示器状态
function updateIndicator() {
const dots = document.querySelectorAll('.dot');
dots.forEach((dot, i) => {
dot.classList.toggle('active', i === currentIndex);
});
}
// 自动轮播
let timer = setInterval(() => {
goToIndex(currentIndex + 1);
}, 3000);
// 鼠标悬停暂停轮播
sliderWrapper.addEventListener('mouseenter', () => clearInterval(timer));
sliderWrapper.addEventListener('mouseleave', () => {
timer = setInterval(() => {
goToIndex(currentIndex + 1);
}, 3000);
});
// 按钮事件
prevBtn.addEventListener('click', () => goToIndex(currentIndex - 1));
nextBtn.addEventListener('click', () => goToIndex(currentIndex + 1));
initIndicator();
});
无限循环优化
通过克隆首尾元素实现无缝轮播:
// 克隆首尾元素
const firstItem = sliderItems[0].cloneNode(true);
const lastItem = sliderItems[totalItems - 1].cloneNode(true);
sliderWrapper.appendChild(firstItem);
sliderWrapper.insertBefore(lastItem, sliderItems[0]);
// 调整初始位置
sliderWrapper.style.transform = 'translateX(-100%)';
currentIndex = 1;
// 修改切换逻辑
function goToIndex(index) {
currentIndex = index;
sliderWrapper.style.transition = 'transform 0.5s ease';
sliderWrapper.style.transform = `translateX(-${currentIndex * 100}%)`;
// 边界检测
if (currentIndex === totalItems + 1) {
setTimeout(() => {
sliderWrapper.style.transition = 'none';
currentIndex = 1;
sliderWrapper.style.transform = `translateX(-${currentIndex * 100}%)`;
}, 500);
} else if (currentIndex === 0) {
setTimeout(() => {
sliderWrapper.style.transition = 'none';
currentIndex = totalItems;
sliderWrapper.style.transform = `translateX(-${currentIndex * 100}%)`;
}, 500);
}
}
触摸事件支持
添加移动端触摸滑动支持:
let startX = 0;
let moveX = 0;
sliderWrapper.addEventListener('touchstart', (e) => {
startX = e.touches[0].clientX;
clearInterval(timer);
});
sliderWrapper.addEventListener('touchmove', (e) => {
moveX = e.touches[0].clientX - startX;
sliderWrapper.style.transform = `translateX(calc(-${currentIndex * 100}% + ${moveX}px))`;
});
sliderWrapper.addEventListener('touchend', () => {
if (moveX > 50) {
goToIndex(currentIndex - 1);
} else if (moveX < -50) {
goToIndex(currentIndex + 1);
} else {
sliderWrapper.style.transform = `translateX(-${currentIndex * 100}%)`;
}
timer = setInterval(() => {
goToIndex(currentIndex + 1);
}, 3000);
});






