DAY2-步骤进度条

前言

这个项目来源于GitHub上的一个开源项目https://github.com/bradtraversy/50projects50days,总共有50个用来练手的前端项目,我学习然后复现效果,并记录学习笔记和心得。

效果展示

progress-steps (点击查看)

本项目实现了一个步骤进度条,点击下一步,下一个节点会变色,直到所有节点都变色。

代码实现

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
    }
}

技术要点

  1. 中间的进度条,其实用了两个元素进行表示。第一个是:.progress-box::before伪元素,第二个是:.progress。这两个元素高度,位置都一样,不一样的是,伪元素的背景色为偏黑的未激活色,而.progress为蓝色的激活色。但是.progress的默认宽度为0,后续通过js调整宽度,达到颜色变成的目的。

    写这里的时候我偷看了一下作者的实现,因为我想通过background-size去改变颜色的宽度,后来发现这个属性只有在用图片背景的时候才会生效

  2. 项目中的布局基本还是用的flex布局

  3. 中间的进度条的宽度和父容器是一样大的话,但是会超过圆圈2px(如下图),我不知道为什么,知道原因的可以留言告诉我一下。

    image-20221012152223789

    所以,我通过减少中间进度条的长度和在js控制长度时减少1%来间接解决了这个问题。

总结

在js部分我写的比较复杂了,我认为作者的实现方式比我的好。我的代码太冗余了。他是通过计数的方式控制的,而我是通过元素索引的方式控制。


DAY2-步骤进度条
https://www.zhaojun.inkhttps://www.zhaojun.ink/archives/day2-progress-steps
作者
卑微幻想家
发布于
2022-10-12
许可协议