轮播图必须用clearinterval清理旧定时器,否则会失控;推荐display:none切换、固定容器高度、检查img.complete、用button做导航和指示器,并在视口内启动定时器。

setInterval 必须配 clearInterval,否则轮播会失控——这是最常被忽略的实操前提。
为什么轮播图一动就乱?setInterval 没清理干净
常见错误现象:鼠标悬停后图片还在切;点一次“下一张”,0.5秒后又自动切;刷新页面后轮播加速两倍。根本原因都是旧定时器没清掉,新定时器又启动了。
实操建议:
- 定义全局变量
let carouselTimer = null,每次调用setInterval前先执行clearInterval(carouselTimer) -
next()和prev()函数末尾必须调用重置定时器的逻辑(比如resetTimer()),否则手动操作后自动播放节奏错乱 - 不要在
setInterval回调里直接写 DOM 操作,封装成showImage(index)再调用,方便统一控制和调试 - 移动端无
mouseenter,所以 hover 暂停逻辑只应在桌面端启用;若需全平台暂停,改用focusin+blur或显式按钮控制
display: none 切换图片最稳,但容器高度得锁死
用 display: none / display: block 控制显隐,是兼容性最好、性能最高、逻辑最直白的方式。但它有个硬约束:父容器高度不能随图片内容浮动。
实操建议:
- 给轮播容器(如
<div class="carousel">)设固定高度,例如 <code>height: 400px,避免切换时重排导致页面跳动 - 所有
<img>标签必须带width和height属性(或 CSS 固定尺寸),否则加载中会塌陷 - 别用
visibility: hidden替代 —— 它占位,可能撑高容器;也别用opacity: 0—— 透明但仍响应点击,且动画需额外加transition - 初始状态统一设
style="display: none;",第一张图再单独加style="display: block;",顺序不能反 - 外层用
<div class="carousel">,里面直接放多个独立 <code><img src="..." alt="...">,不嵌套、不包裹 - 导航按钮用
<button type="button" data-index="0"></button>,不用<a></a>或<span></span>,避免默认跳转或焦点问题 - 指示器(dots)用
<button type="button"></button>而非<li>,语义清晰、可访问性好、支持disabled - 别把多张图塞进单个
src属性——src只接受一个 URL,写成src="a.jpg,b.jpg"是无效的 - 切换前用
if (images[currentIndex].complete)判断,不满足则跳过本次切换,等下次定时器再试 - 对首屏轮播,可配合
IntersectionObserver监听进入视口后再启动定时器,避免离屏时浪费资源 - 懒加载属性(如
loading="lazy")和轮播逻辑冲突,首次轮播前应提前触发加载,或干脆关掉 - 不要依赖
onload给每张图绑定回调来启动轮播——异步不可控,容易漏掉或重复绑定
图片结构别套复杂标签,<div class="carousel"> 包 <code><img> 就够
初学者容易过早引入 <picture></picture>、<figure></figure> 或动态生成 DOM,结果卡在结构解析上。最稳妥的起点就是扁平化结构。
实操建议:
img.complete 得检查,否则网络慢时轮播会闪白屏
自动轮播如果只靠计时器驱动,不判断图片是否加载完成,就会在图片还没解码完时强行显示,造成空白帧或错位。
实操建议:











