【前端】原生 JS 实现轮播图
Dandelion 10/2/2022 JS
# 概述
# 实现原理
轮播图的实现:所有轮播图片横向排列,窗口范围内只显示一张图片,窗口外的图片隐藏,每次切换即移动一张图片的距离。
图片移动的方式:translate
/position
- 实现细节如下:
- 图片自动播放
- 点击中间圆点按钮,实现图片任意切换
- 点击左右箭头按钮,实现图片左右切换
- 图片的切换对应小圆点的样式变化,即每一个小圆点对应一张图片
- 当鼠标在图片上、左箭头、右箭头时清除定时器,即图片不轮播
- 当鼠标离开图片、左箭头、右箭头时开启定时器,即图片继续轮播
- 轮播图切换的动画效果
- 问题:当切换到最后一张图片后,再切换应该是第一张,依然需要同样的过渡效果,如何实现无缝切换?
- 思路:在最后一张图片后再新增第一张图片,所有图片切换完毕之后,趁机切换回第一张(无过渡效果)重新开始
- 实现的关键点
- 全局声明 index 变量记录当前是第几张图片,这样无论是点击左右箭头还是小圆点都能继续下一步操作
- 通过在轮播图的前面和后面放置
跳板图片
,实现图片的无缝播放
# HTML
<link rel="stylesheet" href="./demo.css" />
<div class="banner_container">
<ul class="img_box">
<li><img src="图片4" alt="" /></li>
<li><img src="图片1" alt="" /></li>
<li><img src="图片2" alt="" /></li>
<li><img src="图片3" alt="" /></li>
<li><img src="图片4" alt="" /></li>
<li><img src="图片1" alt="" /></li>
</ul>
<ul class="sel_box">
<li data-index="0"></li>
<li data-index="1"></li>
<li data-index="2"></li>
<li data-index="3"></li>
</ul>
<div class="left_btn"><</div>
<div class="right_btn">></div>
</div>
<script src="./demo.js"></script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# CSS
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.banner_container {
position: relative;
margin: 100px;
width: 400px;
height: 250px;
overflow: hidden;
}
ul.img_box {
position: absolute;
left: 0;
top: 0;
transform: translateX(-400px);
}
.img_box li {
float: left;
list-style: none;
}
.img_box li img {
width: 400px;
}
.sel_box {
position: absolute;
bottom: 15px;
left: 50%;
transform: translateX(-50%);
}
.sel_box li {
list-style: none;
display: inline-block;
width: 10px;
height: 10px;
background-color: pink;
margin-right: 3px;
border-radius: 5px;
transition: all 0.4s;
}
.left_btn {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
width: 25px;
height: 30px;
background-color: #fff;
line-height: 30px;
padding-left: 3px;
cursor: pointer;
}
.right_btn {
position: absolute;
top: 50%;
left: 375px;
transform: translateY(-50%);
width: 25px;
height: 30px;
background-color: #fff;
line-height: 30px;
padding-left: 5px;
cursor: pointer;
}
.sel_box .cur {
background-color: red !important;
transform: scale(1.3);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# JS
let imgBox = document.querySelector('.img_box');
let imgs = document.querySelectorAll('img');
let selBox = document.querySelector('.sel_box');
let sels = selBox.querySelectorAll('li');
let leftBtn = document.querySelector('.left_btn');
let rightBtn = document.querySelector('.right_btn');
let index = 0;
let timer = null;
let imgContainerW = imgBox.offsetWidth;
imgBox.style.width = imgContainerW * imgs.length + 'px';
imgBox.style.left = 0 + 'px';
sels[0].className = 'cur';
function swapImg() {
imgBox.style.left = -index * imgContainerW + 'px';
for (let i = 0; i < sels.length; i++) {
sels[i].className = '';
}
list[index].className = 'cur';
}
function swapFormat() {
index++;
if (index >= 4) {
index = 4;
imgBox.style.transition = 'all, linear, 1s';
imgBox.style.left = -index * imgContainerW + 'px';
for (let i = 0; i < sels.length; i++) {
sels[i].className = '';
}
list[0].className = 'cur';
setTimeout(function () {
index = 0;
imgBox.style.transition = '';
swapImg();
}, 1500);
} else {
imgBox.style.transition = 'all, linear, 1.5s';
swapImg();
}
}
timer = setInterval(swapFormat, 3000);
rightBtn.addEventListener('click', function () {
swapFormat();
});
leftBtn.addEventListener('click', function () {
index--;
if (index < 0) {
index = -1;
imgBox.style.transition = 'all, linear, 1.5s';
imgBox.style.left = -index * imgContainerW + 'px';
for (let i = 0; i < sels.length; i++) {
sels[i].className = '';
}
sels[3].className = 'cur';
setTimeout(function () {
index = 3;
imgBox.style.transition = '';
swapImg();
}, 1000);
} else {
imgBox.style.transition = 'all, linear, 1.5s';
swapImg();
}
});
imgBox.addEventListener('mouseover', function () {
clearInterval(timer);
});
rightBtn.addEventListener('mouseover', function () {
clearInterval(timer);
});
leftBtn.addEventListener('mouseover', function () {
clearInterval(timer);
});
imgBox.addEventListener('mouseout', function () {
timer = setInterval(swapFormat, 3000);
});
leftBtn.addEventListener('mouseout', function () {
timer = setInterval(swapFormat, 3000);
});
rightBtn.addEventListener('mouseout', function () {
timer = setInterval(swapFormat, 3000);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94