轮播图应使用div套img结构,禁用ul/li和picture;定时器需统一管理,每次操作前clearInterval再重设;切换图片须先归零所有display,再显示当前项。

轮播图结构必须用 div 套 img,别用 ul/li 或 picture
浏览器不认“轮播”这个语义,只认 DOM 层级和样式规则。用 ul/li 包 img 看似语义正确,但会多一层默认 list-style 和 margin,容易撑开容器高度;picture 带 srcset 和 media 查询,在轮播逻辑未稳时反而干扰调试。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 外层容器统一用
div class="carousel" - 图片直接放
div class="carousel-images"里,每张是独立img标签 - 所有
img初始加style="display: none;",第一张额外加style="display: block;" - 别给
img设width/height行内属性,改用 CSS 控制尺寸,避免拉伸变形
setInterval 启动前必须先 clearInterval 已有定时器
用户点一次“下一张”,再悬停,再点按钮,再移开——这些操作都会触发 next() 或 resetTimer(),若不清理旧定时器,多个 setInterval 并发运行,图片就会跳帧、乱序、甚至卡死。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 声明全局变量
let intervalId = null - 每次启动前写
clearInterval(intervalId),再赋新值:intervalId = setInterval(...) - 在
next()、prev()、goTo(index)结尾都调用resetTimer() - 给
.carousel绑mouseenter/mouseleave,暂停/恢复定时器(移动端可忽略)
切换图片时必须先清空所有 display: block,再设当前项
常见错误现象:第2张显示时,第1张还半透明残留;或点击后两张同时 visible。根源是没做“归零”动作——JS 只加了 display: block,但没把之前显式的那张设回 none。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 封装函数
showImage(index),开头就遍历所有img元素,统一设style.display = 'none' - 再取
imgs[index % imgs.length]设style.display = 'block'(取余实现循环) - 不要用
visibility: hidden替代display: none,前者仍占文档流,可能撑高容器 - 如果用
opacity+transition做淡入淡出,也要同步控制pointer-events: none防止误点隐藏图
自动轮播的计时逻辑不能和手动操作解耦
很多初学者写完 setInterval(() => next(), 3000) 就以为完成,结果用户点按钮后图片继续按原节奏跳,体验极差。自动轮播不是“后台服务”,而是“默认行为”,一旦用户干预,就得重置节奏。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 每次用户点击按钮、悬停进入、拖拽(如有)、或调用
goTo(),都应立即执行resetTimer() -
resetTimer()内部:先clearInterval(intervalId),再intervalId = setInterval(...) - 别在
setInterval回调里直接写 DOM 操作,全部收进next(),方便复用和测试 - 移动端无 hover,
mouseenter/mouseleave可跳过,专注 touchstart/touchend 的节流处理(如需)
最易被忽略的是定时器生命周期管理——它不像变量赋值那样直观,一旦漏掉 clearInterval,问题不会立刻报错,而是在用户反复交互后逐渐暴露。轮播图的“动”是假象,真正的难点永远在“停得准、起得稳”。



















