纯html无法实现轮播,必须用javascript控制dom;最稳妥起点是setinterval配合queryselector切换display显隐,需统一设none再设block、固定容器高度、检查img.complete、妥善管理定时器。

纯 HTML 无法实现轮播,必须靠 JavaScript 控制 DOM 更新;最稳妥的起点是 setInterval + querySelector 切换显隐状态,而不是一上来就写 transform 动画或引入 Swiper。
用 display: none 切换图片最简单,但顺序和重排容易出错
核心逻辑就是让所有 <img> 默认 display: none,只把当前那张设为 display: block。看似简单,但踩坑点很集中:
- 切换前必须先遍历所有
<img>,统一设回display: none,再设目标项为block—— 顺序反了就会残留上一张 - 如果轮播容器高度不固定(比如图片宽高不一致),
display切换会触发重排,导致页面跳动;此时必须给容器设死高度,例如height: 400px - 别用
visibility: hidden或opacity: 0替代 —— 前者占位影响布局,后者仍响应事件且需额外加transition - 每张图必须带
alt和明确宽高属性(如width="600" height="400"),否则加载时布局抖动
setInterval 必须配 clearInterval,否则定时器会堆叠
只写 setInterval(switchImage, 3000) 是危险操作:用户点按钮、鼠标悬停、页面切到后台再切回来,都可能让多个定时器并发运行,结果就是图片狂闪或乱序跳转。
- 定义全局变量
let carouselTimer = null,每次调用setInterval前先执行clearInterval(carouselTimer) -
mouseenter时清掉定时器,mouseleave时重新启动(注意:移动端无 hover,这段可不加) - 手动点击左右按钮或指示点后,也要立即调用
clearInterval(carouselTimer)再重设,否则刚切到第 2 张,0.5 秒后又自动切到第 3 张 - 别用
setTimeout递归模拟 —— 容易栈溢出,且无法统一清理
图片加载未完成就切换,会导致空白帧
网络慢或图片体积大时,src 改了但还没加载完,display: block 一设,就是白屏或占位符。不能靠“等几秒”这种经验主义。
- 切换前检查
img.complete,为false就跳过本次切换,等下一轮再试 - 别用
img.onload绑定后再切 —— 首次加载完才开始轮播,体验断层;应该轮播照跑,只是跳过未就绪的帧 - 如果首图
img.complete === false,说明它本身没加载好,得在初始化阶段就处理(比如加 loading 状态或 fallback 占位图)
结构用 <div class="carousel"> 包 <code><img>,别套 <ul></ul> 或 <picture></picture>
初学最容易在结构上绕弯子:有人把图片塞进 <ul><li><img></li></ul>,有人一上来就加 <source></source> 做响应式,结果 JS 找元素、CSS 控制显隐全变复杂。
- 外层用
<div class="carousel">,所有轮播相关元素(图片、按钮、指示点)都放里面,方便后续选中和样式隔离 <li>图片直接平铺在容器内,每个都是独立 <code><img src="..." alt="...">,不要嵌套在<figure></figure>或<picture></picture>里(除非你明确需要语义化或响应式源切换) - 导航按钮用
<button type="button"></button>,带data-index属性,避免用<a></a>导致默认跳转,也别用<span></span>导致不可聚焦或禁用失效 - 不要试图用单个
<img src="a.jpg,b.jpg,c.jpg">——src只接受一个 URL,这样写根本不会加载任何图
真正难的不是让图片动起来,而是让动的过程不崩、不闪、不卡、不抢资源。从 display 切换起步,把 clearInterval、img.complete、死高度这三件事做稳,后面加 transform 滑动、懒加载、触摸支持才有意义。











