JS实现仿京东首页商品轮播图

近期做了一个面试题,仿照京东首页商品轮播图实现一个轮播图

1. HTML 结构搭建

HTML 部分主要负责构建轮播图的整体结构,包含一个轮播图容器、图片展示区域以及分页器容器:

<div class="carousel">
<div class="carousel-images">
<!-- 多个图片项 -->
<div class="carousel-image active"><img src="1.jpg" alt="Image 1"></div>
<div class="carousel-image"><img src="2.jpg" alt="Image 2"></div>
<!-- 更多图片... -->
</div>
<div class="pagination"></div>
</div>
  • .carousel:作为轮播图的整体容器,用于包裹图片展示区域和分页器。
  • .carousel-images:用于存放所有轮播图片的容器。
  • .carousel-image:每个图片项的容器,初始状态下只有带有 active 类的图片项会显示。
  • .pagination:分页器容器,后续会通过 JavaScript 动态创建分页点。

2. CSS 样式设计

CSS 部分为轮播图添加样式,实现布局和渐隐渐显效果:

.carousel {
position: relative;
width: 80%;
margin: auto;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
height: 750px;
width: 522px;
}

.carousel-image {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 1s ease;
}

.carousel-image.active {
opacity: 1;
}
  • .carousel:设置相对定位,方便内部元素进行绝对定位,同时设置宽度、边距、圆角、阴影和溢出隐藏等样式。
  • .carousel-image:设置绝对定位,使其重叠显示,初始透明度为 0,通过 transition 属性实现渐隐渐显效果。
  • .carousel-image.active:当图片项带有 active 类时,透明度为 1,即显示该图片。

3. JavaScript 功能实现

3.1 变量初始化

const images = document.querySelectorAll('.carousel-image');
const pagination = document.querySelector('.pagination');
let currentIndex = 0;
let timer;
  • images:获取所有的图片项元素。
  • pagination:获取分页器容器元素。
  • currentIndex:记录当前显示图片的索引,初始值为 0。
  • timer:用于存储自动播放的定时器 ID。

3.2 分页器创建

images.forEach((_, index) => {
const dot = document.createElement('span');
dot.classList.add('dot');
dot.dataset.index = index;
dot.addEventListener('click', () => {
clearInterval(timer);
currentIndex = index;
updateCarousel();
startAutoPlay();
});
pagination.appendChild(dot);
});
  • 遍历所有图片项,为每个图片项创建一个分页点(<span> 元素),并添加 dot 类。
  • 为每个分页点设置 data-index 属性,用于记录其对应的图片索引。
  • 为每个分页点添加点击事件监听器,点击时清除当前定时器,更新 currentIndex 为点击的分页点对应的索引,调用 updateCarousel() 函数切换图片,然后重新启动定时器。

3.3 图片切换函数

const updateCarousel = () => {
images.forEach((image, index) => {
image.classList.remove('active');
if (index === currentIndex) {
image.classList.add('active');
}
});

document.querySelectorAll('.dot').forEach(dot => dot.classList.remove('active'));
document.querySelectorAll('.dot')[currentIndex].classList.add('active');
};
  • 遍历所有图片项,移除所有图片项的 active 类,然后为当前索引对应的图片项添加 active 类,实现图片的切换。
  • 同样,遍历所有分页点,移除所有分页点的 active 类,然后为当前索引对应的分页点添加 active 类,更新分页器状态。

3.4 自动播放函数

const startAutoPlay = () => {
timer = setInterval(() => {
currentIndex = (currentIndex + 1) % images.length;
updateCarousel();
}, 1000);
};
  • 使用 setInterval 函数创建一个定时器,每隔 1 秒执行一次回调函数。
  • 在回调函数中,更新 currentIndex 为下一张图片的索引(使用取模运算符确保索引不会越界),然后调用 updateCarousel() 函数切换图片。

3.5 初始化操作

updateCarousel();
startAutoPlay();
  • 调用 updateCarousel() 函数进行初始化,显示第一张图片并更新分页器状态。
  • 调用 startAutoPlay() 函数启动自动播放功能。

综上所述,通过 HTML 构建结构、CSS 设置样式和 JavaScript 实现交互逻辑,完成了一个具有渐隐渐显效果、支持自动播放和手动切换的轮播图。

4.全部代码

<!DOCTYPE html>
<html lang="zh">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水平轮播图</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 50px;
text-align: center;
width: 522px;
height: 750px;
}

.carousel {
position: relative;
width: 80%;
margin: auto;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
/* 设置一个合适的高度,可根据实际图片比例调整 */
height: 750px;
width: 522px;
}

.carousel-images {
position: relative;
width: 100%;
height: 100%;
}

.carousel-image {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 1s ease;
}

.carousel-image.active {
opacity: 1;
}

.carousel img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 10px;
display: block;
}

.pagination {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
text-align: center;
z-index: 1;
}

.dot {
display: inline-block;
width: 10px;
height: 10px;
margin: 0 5px;
border-radius: 50%;
background-color: #bbb;
cursor: pointer;
}

.dot.active {
background-color: #717171;
}
</style>
</head>

<body>

<div class="carousel">
<div class="carousel-images">
<div class="carousel-image active"><img src="1.jpg" alt="Image 1"></div>
<div class="carousel-image"><img src="2.jpg" alt="Image 2"></div>
<div class="carousel-image"><img src="3.jpg" alt="Image 3"></div>
<div class="carousel-image"><img src="4.jpg" alt="Image 4"></div>
<div class="carousel-image"><img src="5.jpg" alt="Image 5"></div>
<div class="carousel-image"><img src="6.jpg" alt="Image 6"></div>
</div>
<div class="pagination"></div>
</div>

<script>
const images = document.querySelectorAll('.carousel-image');
const pagination = document.querySelector('.pagination');
let currentIndex = 0;
let timer;

// 创建分页器
images.forEach((_, index) => {
const dot = document.createElement('span');
dot.classList.add('dot');
dot.dataset.index = index;
dot.addEventListener('click', () => {
// 清除当前定时器
clearInterval(timer);
currentIndex = index;
updateCarousel();
// 重新启动定时器
startAutoPlay();
});
pagination.appendChild(dot);
});

const updateCarousel = () => {
images.forEach((image, index) => {
image.classList.remove('active');
if (index === currentIndex) {
image.classList.add('active');
}
});

// 更新分页器状态
document.querySelectorAll('.dot').forEach(dot => dot.classList.remove('active'));
document.querySelectorAll('.dot')[currentIndex].classList.add('active');
};

const startAutoPlay = () => {
timer = setInterval(() => {
currentIndex = (currentIndex + 1) % images.length;
updateCarousel();
}, 1000);
};

// 初始化
updateCarousel();
// 启动自动播放
startAutoPlay();
</script>

</body>

</html>