✨ 功能描述:
-
显示一张图片。
-
有“上一张 / 下一张”两个按钮
-
自动轮播,每隔 3 秒切换一张
💡 技术点练习:
-
数组索引循环
-
DOM 操作
-
使用
setInterval()
实现自动切换 -
对用户状态的可视反馈
页面结构(HTML 参考):
<div class="carousel">
<img id="carouselImage" src="" alt="轮播图">
<button id="prevBtn">上一张</button>
<button id="nextBtn">下一张</button>
</div>
实践代码如下:
const carouselImage = document.getElementById('carouselImage')
const prevBtn = document.getElementById('prevBtn')
const nextBtn = document.getElementById('nextBtn')
const images = [
'https://picsum.photos/id/1015/400/200',
'https://picsum.photos/id/1025/400/200',
'https://picsum.photos/id/1035/400/200'
];
let timer = null
let intervalTime = 3000
let currentIndex = 0
// 显示当前图片
const showImage = (imagesIndex) => {
carouselImage.src = images[imagesIndex]
}
// 上一张
prevBtn.addEventListener('click', () => {
currentIndex = (currentIndex - 1 + images.length) % images.length
showImage(currentIndex)
resetInterval() // 用户手动操作时,重置自动轮播计时
})
// 下一张
nextBtn.addEventListener('click', () => {
currentIndex = (currentIndex + 1) % images.length
showImage(currentIndex)
resetInterval() // 用户手动操作时,重置自动轮播计时
})
// 初始显示
showImage(currentIndex)
timer = setInterval(() => {
currentIndex = (currentIndex + 1) % images.length
showImage(currentIndex)
}, intervalTime);
const resetInterval = () => {
clearInterval(timer)
timer = setInterval(() => {
currentIndex = (currentIndex + 1) % images.length
showImage(currentIndex)
}, intervalTime);
}
页面效果展示 :
额外知识记录:
✅ 上一张的下标循环为什么是(currentIndex - 1 + images.length) % images.length?
假设我们当前在第 currentIndex
张,想获取“上一张”的索引:
-
最自然的想法是:
currentIndex - 1
-
但当
currentIndex = 0
,这样就变成-1
,索引不合法。
所以我们想“借助长度来回滚”:currentIndex - 1 + images.length
如果 currentIndex 是 0,这里就是
-1 + 3 = 2
,正好是最后一张。 -
再加一个
% images.length
,是为了让最终值始终保持在合法范围:(currentIndex - 1 + images.length) % images.length
✅ 为什么要在用户手动操作时加 resetInterval()?
原因:
- 当你用
setInterval
实现自动轮播时,图片会每隔固定时间自动切换。- 但如果你手动点击“上一张”或“下一张”按钮,手动切换了图片,自动切换的定时器其实还在跑着,没有停。
- 假设定时器每3秒切一次,手动点了按钮后,马上1秒后定时器又切了,这样手动切换的效果就很快被自动切换“覆盖”,用户体验不好。
resetInterval()
的作用就是:
清除当前的自动切换定时器(
clearInterval(timer)
),让旧的计时器停止;重新启动一个新的定时器,重新计时3秒后再自动切换。
这样做的好处:
手动切换后,会“重新计时”3秒,再自动切换,避免自动切换太快打断用户的操作感;
保证自动切换的节奏是从用户操作时重新开始算起,更自然。