纯css无法实现完整轮播,必须结合js控制图片切换、定时器和用户交互;核心是单img标签+opacity过渡+src动态更新,并需处理加载、节流、触摸滑动等细节。

用 CSS 动画 + JavaScript 控制 opacity 实现淡入淡出轮播
纯 CSS 能做淡入淡出,但轮播需要切换图片、控制定时器、响应用户操作——必须加 JS。核心思路是:只保留一张 <img> 标签,通过修改其 src 和 opacity 配合 CSS 过渡达成视觉轮播效果,避免 DOM 频繁增删。
常见错误是直接对多张 <img> 用 display: none 切换,这会导致 opacity 动画失效(display 变化会中断过渡);或用 visibility: hidden 但未设初始 opacity: 0,造成闪现。
- 给
<img>设置transition: opacity 0.5s ease-in-out,且始终保留在 DOM 中 - 每次切换前先设
opacity: 0,等动画结束(可用setTimeout或transitionend事件)再更新src,最后设opacity: 1 - 避免在
transitionend中连续触发多次(比如快速点击下一张),建议加节流或用标志位isTransitioning锁住
setInterval 轮播 + 手动暂停的可靠写法
自动轮播不能只靠 setInterval 无脑执行,否则用户点击后可能立刻又被下一张覆盖。必须在用户交互时清除旧定时器,并在离开交互区域后重新启动。
典型场景:鼠标悬停轮播容器时暂停,移出后 3 秒恢复;点击左右箭头也应重置定时器。
- 用变量
let autoPlayTimer = null存储当前定时器 ID - 每次开始轮播前先
clearInterval(autoPlayTimer),再autoPlayTimer = setInterval(...) - 在
mouseenter事件里clearInterval(autoPlayTimer),mouseleave里重启(可加setTimeout延迟 3 秒) - 不要在
setInterval回调里直接操作 DOM 属性(如img.src = ...),应封装成独立函数如showNextImage(),便于复用和测试
解决图片加载空白与闪动的关键点
切换 src 瞬间,浏览器需加载新图,若网络慢或图片大,会出现白屏或旧图残留。这不是动画问题,而是资源加载时机没处理好。
错误做法:设完 src 就立刻设 opacity: 1;正确做法是等新图加载完成再触发动画。
- 用
img.addEventListener('load', handler)监听加载成功,失败则用error事件兜底 - 加载中可临时显示 loading 占位图(如 base64 小灰块),或保持上一张图的
opacity: 1不变,直到新图 ready - 避免在
load回调里再次设置opacity导致动画重复(比如刚设完 0,又设 1,中间没 delay)——应在 load 后调用统一的「显示当前图」逻辑 - 预加载下一张图:在当前图显示后,用
new Image().src = nextSrc提前触发下载,不插入 DOM
移动端触摸滑动支持的最小可行方案
仅靠点击按钮不够,用户习惯左右滑。不需要引入 Hammer.js 这类库,原生 touchstart/touchmove/touchend 就够用,关键是判断滑动方向与阈值。
容易踩的坑是 touch 事件未阻止默认行为导致页面滚动干扰,或未清除定时器造成滑动后自动跳转错乱。
- 记录
touchstart的clientX,在touchend读取最终位置,差值绝对值 > 50px 才视为有效滑动 - 滑动结束时立即
clearInterval(autoPlayTimer),并根据方向调用showPrevImage()或showNextImage() - 在
touchstart里加e.preventDefault()防止页面跟着拖拽滚动(但注意别影响内部可滚动区域) - 为兼容 iOS Safari,
<img>外层容器加style="max-width:90%",允许垂直滚动但禁用水平拖拽冲突
轮播最麻烦的从来不是动画本身,而是加载、定时器、交互状态三者之间的耦合。一个没清理的 setInterval,一张没监听 load 的图片,一次没防抖的 transitionend,都足以让淡入淡出变成卡顿或错乱。动手前先想清楚谁该负责清理,谁该负责等待,比写十行动画代码更重要。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











