- 最终效果预览
- 准备工作
- 第一步:基础 HTML 结构
- 第二步:CSS 样式美化
- 第三步:JavaScript 核心逻辑实现
- 自动播放
- 指示器点击切换
- 左右箭头切换
- 无缝循环效果
- 第四步:整合与优化
- 完整代码
- 进阶与扩展
最终效果预览
在开始之前,我们先看看我们要制作的东西是什么样的,它应该包含:

(图片来源网络,侵删)
- 一系列可以自动切换的图片。
- 底部有圆点指示器,显示当前是第几张图片,并可以点击切换。
- 左右两侧有箭头,可以手动切换到上一张或下一张。
- 切换时有平滑的过渡动画。
准备工作
你需要准备以下三样东西:
- HTML 文件: 创建一个
index.html文件。 - CSS 文件: 创建一个
style.css文件。 - JavaScript 文件: 创建一个
script.js文件。 - 图片: 准备几张你想要轮播的图片,并放在一个名为
images的文件夹里,为了演示,你可以使用unsplash.com上的随机图片。
第一步:基础 HTML 结构
我们用 HTML 搭建轮播图的“骨架”,打开 index.html 文件,输入以下代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">JavaScript 图片轮播</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="carousel-container">
<!-- 图片容器 -->
<div class="carousel-slides">
<!-- 使用 data-index 来追踪图片的索引 -->
<div class="carousel-slide active" data-index="0">
<img src="images/slide1.jpg" alt="Slide 1">
</div>
<div class="carousel-slide" data-index="1">
<img src="images/slide2.jpg" alt="Slide 2">
</div>
<div class="carousel-slide" data-index="2">
<img src="images/slide3.jpg" alt="Slide 3">
</div>
<div class="carousel-slide" data-index="3">
<img src="images/slide4.jpg" alt="Slide 4">
</div>
</div>
<!-- 左右箭头 -->
<button class="carousel-btn prev-btn">❮</button>
<button class="carousel-btn next-btn">❯</button>
<!-- 指示器 -->
<div class="carousel-indicators">
<span class="indicator active" data-index="0"></span>
<span class="indicator" data-index="1"></span>
<span class="indicator" data-index="2"></span>
<span class="indicator" data-index="3"></span>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
代码解释:
.carousel-container: 最外层的容器,用于包裹整个轮播组件。.carousel-slides: 包含所有图片的容器。.carousel-slide: 单张图片的容器,我们给第一张图片添加了active类,表示它是当前显示的图片。data-index属性用于标记图片的顺序(从0开始)。.carousel-btn: 左右箭头按钮。.carousel-indicators: 指示器(小圆点)的容器。.indicator: 单个小圆点,同样,第一个小圆点有active类,并且也有data-index属性。
第二步:CSS 样式美化
我们来添加 CSS 样式,让轮播图看起来像模像样,打开 style.css 文件,输入以下代码:

(图片来源网络,侵删)
/* 基础重置和样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f4f4f4;
}
/* 轮播图容器 */
.carousel-container {
position: relative;
width: 800px;
max-width: 100%; /* 响应式 */
overflow: hidden; /* 隐藏溢出的图片 */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
/* 图片容器 - 这是实现切换效果的关键 */
.carousel-slides {
display: flex; /* 使用 Flexbox 布局 */
transition: transform 0.5s ease-in-out; /* 添加平滑过渡效果 */
}
/* 单张图片 */
.carousel-slide {
min-width: 100%; /* 每张图片占据容器的100%宽度 */
height: 400px;
}
.carousel-slide img {
width: 100%;
height: 100%;
object-fit: cover; /* 保证图片填充且不变形 */
}
/* 左右箭头 */
.carousel-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.5);
color: white;
border: none;
font-size: 24px;
padding: 10px 15px;
cursor: pointer;
border-radius: 50%;
transition: background-color 0.3s ease;
}
.carousel-btn:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.prev-btn {
left: 10px;
}
.next-btn {
right: 10px;
}
/* 指示器 */
.carousel-indicators {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
}
.indicator {
width: 12px;
height: 12px;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 50%;
cursor: pointer;
transition: background-color 0.3s ease;
}
.indicator.active {
background-color: white;
}
代码解释:
.carousel-container设置了overflow: hidden,这样当图片移动时,超出容器的部分就会被隐藏。.carousel-slides使用display: flex让所有图片排成一行。transition: transform是核心,它会让transform属性的变化(如平移)产生平滑的动画。.carousel-slide设置min-width: 100%确保每张图片都占据一行。.carousel-btn使用position: absolute将按钮定位在图片的两侧。.indicator定义了小圆点的样式,.active类用于高亮当前指示器。
第三步:JavaScript 核心逻辑
这是最关键的一步,我们将用 JavaScript 来控制轮播图的行为,打开 script.js 文件,让我们一步步实现功能。
1 获取 DOM 元素和初始化变量
我们需要获取 HTML 中我们需要的元素,并定义一些变量来管理轮播状态。
document.addEventListener('DOMContentLoaded', () => {
// 1. 获取所有需要的 DOM 元素
const slides = document.querySelectorAll('.carousel-slide');
const indicators = document.querySelectorAll('.indicator');
const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
const slidesContainer = document.querySelector('.carousel-slides');
// 2. 初始化变量
let currentIndex = 0; // 当前显示的图片索引
const totalSlides = slides.length; // 图片总数
let slideInterval; // 用于存储定时器的变量
const intervalTime = 3000; // 自动切换的时间间隔(毫秒)
// ... 接下来我们将在这里添加其他函数 ...
});
2 核心函数:goToSlide(index)
这个函数是轮播图的“大脑”,它负责将轮播图切换到指定的索引位置。

(图片来源网络,侵删)
// 在 script.js 中添加这个函数
function goToSlide(index) {
// 检查索引是否越界
if (index < 0) {
index = totalSlides - 1; // 如果是负数,跳转到最后一张
} else if (index >= totalSlides) {
index = 0; // 如果超出总数,跳转到第一张
}
// 更新当前索引
currentIndex = index;
// 移动图片容器
// transform: translateX(-${currentIndex * 100}%)
// 意思是:向左移动 当前索引 * 100% 的宽度
slidesContainer.style.transform = `translateX(-${currentIndex * 100}%)`;
// 更新指示器状态
indicators.forEach(indicator => {
indicator.classList.remove('active');
});
indicators[currentIndex].classList.add('active');
}
3 自动播放功能
使用 setInterval 来实现每隔一段时间自动切换到下一张图片。
// 在 script.js 中添加这个函数
function startSlideShow() {
// 清除之前的定时器,防止重复设置
clearInterval(slideInterval);
// 设置新的定时器
slideInterval = setInterval(() => {
goToSlide(currentIndex + 1);
}, intervalTime);
}
4 事件监听器
我们需要将用户的操作(点击箭头、点击指示器)与我们的函数连接起来。
// 在 script.js 的 DOMContentLoaded 事件处理函数内部添加
// 左右箭头点击事件
prevBtn.addEventListener('click', () => {
goToSlide(currentIndex - 1);
startSlideShow(); // 用户操作后重置定时器
});
nextBtn.addEventListener('click', () => {
goToSlide(currentIndex + 1);
startSlideShow(); // 用户操作后重置定时器
});
// 指示器点击事件
indicators.forEach(indicator => {
indicator.addEventListener('click', () => {
const index = parseInt(indicator.getAttribute('data-index'));
goToSlide(index);
startSlideShow(); // 用户操作后重置定时器
});
});
// 鼠标悬停时暂停自动播放
const carouselContainer = document.querySelector('.carousel-container');
carouselContainer.addEventListener('mouseenter', () => {
clearInterval(slideInterval);
});
// 鼠标离开时恢复自动播放
carouselContainer.addEventListener('mouseleave', () => {
startSlideShow();
});
// 页面加载完成后,启动自动播放
startSlideShow();
事件监听器解释:
- 箭头点击: 点击时调用
goToSlide并传入currentIndex + 1或currentIndex - 1。 - 指示器点击: 获取被点击的指示器上的
data-index值,然后调用goToSlide。 - 重置定时器: 每次用户手动操作后,我们调用
startSlideShow(),这会先清除旧的定时器,再设置一个新的,这样做的目的是,用户操作后,轮播图会重新计时,而不是在用户操作后马上又切换。 - 鼠标悬停/离开: 提升用户体验,当鼠标悬停在轮播图上时,暂停自动播放;鼠标离开后,恢复播放。
第四步:整合与优化
将上面所有 JavaScript 代码块整合到 script.js 文件中,并确保它们的顺序正确,完整的 script.js 代码将在下一节给出。
至此,一个功能完整的图片轮播图就已经完成了!
完整代码
为了方便你直接复制使用,这里是三个文件的完整代码。
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">JavaScript 图片轮播</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="carousel-container">
<div class="carousel-slides">
<div class="carousel-slide active" data-index="0">
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80" alt="Slide 1">
</div>
<div class="carousel-slide" data-index="1">
<img src="https://images.unsplash.com/photo-1542291026-7eec264c27ff?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80" alt="Slide 2">
</div>
<div class="carousel-slide" data-index="2">
<img src="https://images.unsplash.com/photo-1518837695005-2083093ee35b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80" alt="Slide 3">
</div>
<div class="carousel-slide" data-index="3">
<img src="https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80" alt="Slide 4">
</div>
</div>
<button class="carousel-btn prev-btn">❮</button>
<button class="carousel-btn next-btn">❯</button>
<div class="carousel-indicators">
<span class="indicator active" data-index="0"></span>
<span class="indicator" data-index="1"></span>
<span class="indicator" data-index="2"></span>
<span class="indicator" data-index="3"></span>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
style.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f4f4f4;
}
.carousel-container {
position: relative;
width: 800px;
max-width: 100%;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.carousel-slides {
display: flex;
transition: transform 0.5s ease-in-out;
}
.carousel-slide {
min-width: 100%;
height: 400px;
}
.carousel-slide img {
width: 100%;
height: 100%;
object-fit: cover;
}
.carousel-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.5);
color: white;
border: none;
font-size: 24px;
padding: 10px 15px;
cursor: pointer;
border-radius: 50%;
transition: background-color 0.3s ease;
}
.carousel-btn:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.prev-btn {
left: 10px;
}
.next-btn {
right: 10px;
}
.carousel-indicators {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
}
.indicator {
width: 12px;
height: 12px;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 50%;
cursor: pointer;
transition: background-color 0.3s ease;
}
.indicator.active {
background-color: white;
}
script.js
document.addEventListener('DOMContentLoaded', () => {
// 1. 获取所有需要的 DOM 元素
const slides = document.querySelectorAll('.carousel-slide');
const indicators = document.querySelectorAll('.indicator');
const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
const slidesContainer = document.querySelector('.carousel-slides');
// 2. 初始化变量
let currentIndex = 0;
const totalSlides = slides.length;
let slideInterval;
const intervalTime = 3000;
// 核心函数:切换到指定索引的幻灯片
function goToSlide(index) {
if (index < 0) {
index = totalSlides - 1;
} else if (index >= totalSlides) {
index = 0;
}
currentIndex = index;
slidesContainer.style.transform = `translateX(-${currentIndex * 100}%)`;
indicators.forEach(indicator => {
indicator.classList.remove('active');
});
indicators[currentIndex].classList.add('active');
}
// 自动播放函数
function startSlideShow() {
clearInterval(slideInterval);
slideInterval = setInterval(() => {
goToSlide(currentIndex + 1);
}, intervalTime);
}
// 3. 添加事件监听器
prevBtn.addEventListener('click', () => {
goToSlide(currentIndex - 1);
startSlideShow();
});
nextBtn.addEventListener('click', () => {
goToSlide(currentIndex + 1);
startSlideShow();
});
indicators.forEach(indicator => {
indicator.addEventListener('click', () => {
const index = parseInt(indicator.getAttribute('data-index'));
goToSlide(index);
startSlideShow();
});
});
// 鼠标悬停暂停,离开恢复
const carouselContainer = document.querySelector('.carousel-container');
carouselContainer.addEventListener('mouseenter', () => {
clearInterval(slideInterval);
});
carouselContainer.addEventListener('mouseleave', () => {
startSlideShow();
});
// 4. 启动轮播
startSlideShow();
});
进阶与扩展
当你掌握了基础版本后,可以尝试以下扩展功能来提升你的技能:
- 触摸滑动支持: 使用
touchstart,touchmove, 和touchend事件,让轮播图在手机上可以通过手指滑动来切换。 - 淡入淡出效果: 修改 CSS 和 JavaScript,使用
opacity和z-index来实现图片淡入淡出的切换效果,而不是左右滑动。 - 动态加载图片: 修改 JavaScript,使其从一个数组或 API 动态获取图片 URL,而不是在 HTML 中硬编码,这样轮播图的内容就可以更灵活地更改。
- 使用 CSS 动画: 将
transition替换为更复杂的@keyframes动画,可以实现更酷炫的切换效果。 - 封装成插件/类: 将所有轮播图的逻辑封装到一个 JavaScript 类中,这样你就可以轻松地在页面的不同地方创建多个独立的轮播图实例,而不会互相干扰。
希望这份详细的教程能帮助你成功构建出你的第一个 JavaScript 图片轮播图!祝你编码愉快!
