github:https://github.com/bradtraversy/50projects50days
这个项目的脑洞真的很大,呜呜学到了

一、代码

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Progress Steps</title>
</head>
<body>
<div class="container">
<div class="progress-container">
<div class="progress" id="progress"></div>
<div class="circle active">1</div>
<div class="circle">2</div>
<div class="circle">3</div>
<div class="circle">4</div>
</div>

<button class="btn" id="prev" disabled>Prev</button>
<button class="btn" id="next">Next</button>
</div>
<script src="script.js"></script>
</body>
</html>

CSS

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
95
96
97
98
:root {
--line-border-fill: #3498db;
--line-border-empty: #e0e0e0;
}

* {
box-sizing: border-box;
}

body {
background-color: #f6f7fb;
font-family: 'Muli', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}

.container {
text-align: center;
}

.progress-container {
display: flex;
justify-content: space-between;
position: relative;
margin-bottom: 30px;
max-width: 100%;
width: 350px;
}

.progress-container::before {
content: '';
background-color: var(--line-border-empty);
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
height: 4px;
width: 100%;
z-index: -1;
}

.progress {
background-color: var(--line-border-fill);
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
height: 4px;
width: 0%;
z-index: -1;
transition: 0.4s ease;
}

.circle {
background-color: #fff;
color: #999;
border-radius: 50%;
height: 30px;
width: 30px;
display: flex;
align-items: center;
justify-content: center;
border: 3px solid var(--line-border-empty);
transition: 0.4s ease;
}

.circle.active {
border-color: var(--line-border-fill);
}

.btn {
background-color: var(--line-border-fill);
color: #fff;
border: 0;
border-radius: 6px;
cursor: pointer;
font-family: inherit;
padding: 8px 30px;
margin: 5px;
font-size: 14px;
}

.btn:active {
transform: scale(0.98);
}

.btn:focus {
outline: 0;
}

.btn:disabled {
background-color: var(--line-border-empty);
cursor: not-allowed;
}

Javascript

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
const progress=document.getElementById('progress');
const prev = document.getElementById('prev');
const next = document.getElementById('next');
const circles = document.querySelectorAll('.circle');

let currentActive=1;

next.addEventListener('click',()=>{
currentActive++;
update();
})

prev.addEventListener('click',()=>{
currentActive--;
update();
})

function update(){
circles.forEach((item,index)=>{
if(index<currentActive){
item.classList.add('active');
}
else{
item.classList.remove('active');
}
});

const actives = document.querySelectorAll('.active');
progress.style.width = (actives.length - 1) / (circles.length - 1) * 100 + '%';

if(currentActive===1){
prev.disabled=true;
}
else if(currentActive===circles.length){
next.disabled=true;
}
else{
prev.disabled=false;
next.disabled=false;
}
}

二、知识点心得

(1)css var函数

当css中某一个属性要多次使用时,可以用一个变量存储

1
2
3
4
5
6
7
:root {
--main-bg-color: pink;
}

body {
background-color: var(--main-bg-color);
}

(2)伪元素

伪元素是一个附加至选择器末的关键词,允许我们对被选择元素的特定部分修改样式。一个选择器中只能使用一个伪元素,伪元素必须紧跟在语句中的简单选择器/基础选择器之后。例如::before就可以在首部进行修改。

(3)translateY()、translateX()属性

这个属性可以改变元素在XY轴上的位置

(4)Javascript思路

这个项目中通过对圆圈的颜色和蓝线的长度进行修改来实现视觉效果,设置一个变量来存储当前所在的位置。点击prev变量减一,next变量加一,在每次点击都调用update()函数进行更新,更新的思路是检查index与变量的关系。