DAY2-步骤进度条
前言
这个项目来源于GitHub上的一个开源项目https://github.com/bradtraversy/50projects50days,总共有50个用来练手的前端项目,我学习然后复现效果,并记录学习笔记和心得。
效果展示
本项目实现了一个步骤进度条,点击下一步,下一个节点会变色,直到所有节点都变色。
代码实现
HTML&CSS
<style>
* {
padding: 0;
margin: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #1f1f1f;
color: #fff;
}
.container {
}
.progress-box {
display: flex;
width: 350px;
justify-content: space-between;
position: relative;
}
.progress-box::before {
content: ' ';
width: 99%;
height: 5px;
background-color: #383838;
top: 50%;
z-index: -1;
position: absolute;
}
.step {
width: 28px;
height: 28px;
border: 4px solid #383838;
background-color: #1f1f1f;
border-radius: 50%;
text-align: center;
line-height: 28px;
transition: border .4s ease;
}
.btn {
display: inline-block;
padding: 8px 30px;
font-size: 16px;
border-radius: 5px;
background-color: #383838;
margin-right: 15px;
border: none;
cursor: pointer;
color: #fff;
outline: none;
}
.progress {
width: 0;
height: 5px;
background-color: #3498db;
top: 50%;
z-index: -1;
position: absolute;
transition: width .4s ease;
}
.bottom {
margin-top: 50px;
text-align: center;
cursor: pointer;
}
.step.active {
border: 4px solid #3498db;
}
.btn.active {
background-color: #3498db;
}
.btn:disabled {
background-color: #383838;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="container">
<div class="progress-box">
<div class="step active">1</div>
<div class="step">2</div>
<div class="step">3</div>
<div class="step">4</div>
<div class="step">5</div>
<div class="step">6</div>
<div class="progress"></div>
</div>
<div class="bottom">
<button class="btn" id="prev" disabled>Prev</button>
<button class="btn active" id="next">Next</button>
</div>
</div>
JS
let next = document.querySelector("#next");
let prev = document.querySelector("#prev");
let stepList = document.querySelectorAll(".step");
let progress = document.querySelector(".progress");
next.onclick = () => {
let activeStepList = document.querySelectorAll(".active.step");
if (activeStepList.length < stepList.length) {
prev.disabled = false
prev.classList.add('active')
stepList[activeStepList.length].classList.add('active')
progress.style.width = activeStepList.length / (stepList.length - 1) * 100 - 1 + '%';
if (activeStepList.length + 1 === stepList.length) {
next.disabled = true
next.classList.remove('active')
prev.classList.add('active')
}
return true
}
}
prev.onclick = () => {
let activeStepList = document.querySelectorAll(".active.step");
if (activeStepList.length !== 1) {
next.disabled = false
next.classList.add('active')
stepList[activeStepList.length - 1].classList.remove('active')
progress.style.width = ((activeStepList.length - 2) / (stepList.length - 1)) * 100 + '%';
if (activeStepList.length - 1 === 1) {
prev.disabled = true
prev.classList.remove('active')
next.classList.add('active')
}
return true
}
}
技术要点
-
中间的进度条,其实用了两个元素进行表示。第一个是:
.progress-box::before
伪元素,第二个是:.progress
。这两个元素高度,位置都一样,不一样的是,伪元素的背景色为偏黑的未激活色,而.progress
为蓝色的激活色。但是.progress
的默认宽度为0,后续通过js调整宽度,达到颜色变成的目的。写这里的时候我偷看了一下作者的实现,因为我想通过
background-size
去改变颜色的宽度,后来发现这个属性只有在用图片背景的时候才会生效 -
项目中的布局基本还是用的flex布局
-
中间的进度条的宽度和父容器是一样大的话,但是会超过圆圈2px(如下图),我不知道为什么,知道原因的可以留言告诉我一下。
所以,我通过减少中间进度条的长度和在js控制长度时减少1%来间接解决了这个问题。
总结
在js部分我写的比较复杂了,我认为作者的实现方式比我的好。我的代码太冗余了。他是通过计数的方式控制的,而我是通过元素索引的方式控制。
DAY2-步骤进度条
https://www.zhaojun.inkhttps://www.zhaojun.ink/archives/day2-progress-steps