一个简易版无缝轮播图的实现思路
轮播图应该是每个前端的入门项目了,但是轮播图的无缝切换却难住了不少人,并且我在最近的面试中也被问到了,所以本文将介绍一个简易版的无缝轮播图的实现思路。
思路
无缝轮播图的难点无非就是第一张图和最后一张图的无缝过渡,解决好这一点,剩下的就没什么难度了。
具体实现思路:
- 在第一张图的的前面加一张和最后一张一样的图,同样的,在最后一张图的后面加一张和第一张一样的图。类似下图:
- 当划到最后一张图
copy-1
时,将过渡动画关闭,瞬间切换到 1 图 - 同理,当划到第一张图
copy-n
时,将过渡动画关闭,瞬间切换到 n 图

具体实现:
首先我们准备好以下元素:
html
<div class="banner">
<button class="left-arrow"><</button>
<div class="banner-wrapper">
<div class="banner-wrapper-item banner-copy3">copy-3</div>
<div class="banner-wrapper-item banner-1">1</div>
<div class="banner-wrapper-item banner-2">2</div>
<div class="banner-wrapper-item banner-3">3</div>
<div class="banner-wrapper-item banner-copy1">copy-1</div>
</div>
<button class="right-arrow">></button>
</div>
banner
:轮播图的容器left-arrow
:左箭头banner-wrapper
:轮播图的内部容器,里面放置了五张图片,这里使用 div 来代替 imgbanner-wrapper-item
:轮播图的每一张图片,其中 banner-copy1 和 banner-copy3 是第一张和最后一张图片的复制品right-arrow
:右箭头
然后我们给它们分别添加样式:
css
.banner {
margin: 0 auto;
width: 200px;
height: 200px;
border: 1px solid rgb(0, 0, 0);
overflow: hidden;
position: relative;
}
.banner-wrapper {
display: flex;
transition: transform 0.5s ease-in-out;
transform: translateX(-200px); /* 初始位置 */
}
.banner-wrapper-item {
flex-shrink: 0;
width: 200px; /* 图片宽度 */
height: 200px; /* 图片高度 */
}
.banner-copy3 {
background-color: rgb(154, 170, 212);
}
.banner-1 {
background-color: rgb(168, 230, 166);
}
.banner-2 {
background-color: rgb(209, 174, 174);
}
.banner-3 {
background-color: rgb(154, 170, 212);
}
.banner-copy1 {
background-color: rgb(168, 230, 166);
}
.left-arrow {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
outline: none;
border: none;
cursor: pointer;
z-index: 99;
}
.right-arrow {
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
outline: none;
border: none;
cursor: pointer;
z-index: 99;
}
我们给 banner
容器设置宽高为 200px
, overflow
为 hidden
,并设置 position: relative
,方便后面控制 transform
。
给 banner-wrapper
设置 display: flex
,让内部元素并排排布,通过控制 translateX
来实现图片的切换,并加上过渡效果。
给每个 item
设置宽度和高度为 200px
,并设置背景色。
给 left-arrow
和 right-arrow
设置位置和大小。

获取需要用到的元素:
javascript
const bannerWrapper = document.querySelector('.banner-wrapper');
const leftArrow = document.querySelector('.left-arrow');
const rightArrow = document.querySelector('.right-arrow');
定义一些变量:
javascript
const length = bannerWrapper.children.length; // 图片数量 加上前后复制的一张共五张
let cur = 1; // 当前图片索引,从 0 开始
let width = 200; // 图片宽度
重点来了,给 left-arrow
和 right-arrow
绑定点击事件。
具体讲一下里面的逻辑,以右箭头为例:
- 首先判断当前所以图片是否为最后一张,如果是,则将当前图片索引设置为
1
,并关闭过渡动画,瞬间切换图片1
。 - 当切换到图片
1
后,再将当前图片索引加1
,并开启过渡动画,切换到图片 2 ,这里需要注意,这里需要用setTimeout
函数包一下,不然两次的切换会合并到一起。 - 如果不是最后一张,则将当前图片索引加 1,并设置
transform
值,使得图片切换到下一张。
左箭头同理,下面是具体的代码:
javascript
// 给右箭头绑定点击事件
rightArrow.addEventListener('click', () => {
if (cur === length - 1) {
cur = 1;
bannerWrapper.style.transition = 'none';
bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
setTimeout(() => {
// 让上一个切换完成在执行下一个切换
cur++;
bannerWrapper.style.transition = 'transform 0.5s ease-in-out';
bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
}, 0);
return;
}
cur++;
bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
});
// 给左箭头绑定点击事件
leftArrow.addEventListener('click', () => {
if (cur === 0) {
cur = length - 2;
bannerWrapper.style.transition = 'none';
bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
setTimeout(() => {
// 让上一个切换完成在执行下一个切换
cur--;
bannerWrapper.style.transition = 'transform 0.5s ease-in-out';
bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
}, 0);
return;
}
cur--;
bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
});
到此,一个简单的无缝切换轮播图就完成了。
当然后续还可以加上定时切换和滑动切换的功能,不过无缝轮播的思路都差不多,感兴趣的可以实现一下。
如果有更好的实现方法,欢迎交流。