50 Projects 50 Days - Progress Steps 学习记录

news2024/10/7 18:27:31

50 Projects 50 Days不使用任何前端框架,适合初学者练手,巩固前端基础,在这里记录一下学习过程,尤其是一些细节上的问题。

项目地址

Progress Steps

展示效果

Progress Steps
在这里插入图片描述

实现思路

进度条和结点分开处理:
1. 步骤结点外观通过设置border的圆角和颜色得到;当点击按钮时根据计算将对应结点外边框颜色变更为蓝色。
2. 进度槽默认外观通过伪类before来实现(也可以单独再写一个HTML元素),以父盒子为初始定位,构造一个类似的横线的盒子,层级设置低一些,被结点所覆盖。
3. 进度条的外观则再定义一个和before伪类定位、层级、高度相同的盒子,而它的宽度默认为0,每次点击按钮时通过程序计算改变。

按钮触发的程序:
1. 用一个数字记录目前进度的位置。
2. 进度前的结点设置active类,进度后的移除active类。
3. 对进度条的样式宽度重新计算。
4. 根据当前位置,判断按钮是否还可用。

实现细节

HTML结构

在一个container,主要拆分为进度条和按钮两个区域,因此整体结构划分为progress-containerbutton
progress-container除了几个结点外,再放入一个进度条即可。
button可以再用一个div包起来,也可以直接并排放,本身是行内元素,也可以居中作处理。
buttonprogress设置了一些id,主要在script中使用。

<div class="container">
	<div class="progress-container">
	     <div id="progress"></div>
	     <div class="node active">1</div>
	     <div class="node">2</div>
	     <div class="node">3</div>
	     <div class="node">4</div>
	 </div>
	 <button class="btn" id="prev" disabled>Prev</button>
	 <button class="btn" id="next">Next</button>
 </div>

CSS样式

在全局定义两种经常用到的颜色,方便后面直接使用该CSS变量。

:root{
	--line-border-fill: #3498db;
	--line-border-empty: #383838;
}

containerprogress-container任一元素设置宽度对本次案例效果没有影响。为了让button居中显示,因此用到了text-align属性。

.container{
    width: 350px;
    text-align: center;
}

根据MDN的说明,text-align属性定义行内内容(例如文字)如何相对它的块父元素对齐

progress-container

progress-container设置flex布局,并为子元素绝对定位作为参照父元素设置为相对定位。

.progress-container{
    display: flex;
    justify-content: space-between;
    margin-bottom: 30px;
    position: relative;
    color: #fff;
}

进度槽可以用伪类元素实现,也可以再单独写一个div然后通过绝对定位来实现。相对来说,伪类减少了HTML元素的使用,也可以利用浏览器缓存

另外要注意::before需要定义content,即使是空字符串,否则是不会被浏览器创建。::before::after伪元素的原始目的是在原始元素的主要内容之前和之后插入生成的内容。当没有要插入的内容时,创建一个仅插入任何内容的附加框是没有意义的。因此,none值指示浏览器不要为创建其他框而烦恼。

之后还需要定义长宽的尺寸,设置绝对定位,并从左开始上下居中显示,最后是设置层级靠下,被node元素所覆盖。

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

进度条的实现就与进度槽类似了。

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

这里虽然z-index同样都是-1,但是before元素在DOM流中元素靠前,而进度条靠后,所以进度条层级会更高,覆盖进度槽。这里可以试着把before改为after来验证这一原因,之后再把伪类的z-index改为-2会发现层级又会变下去了。

node元素只要做一个圆形的外观即可,注意将中间的文字设为居中显示。然后设计一个外边框,在active类中改变边框的颜色。

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

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

按钮的外观很简单,设置padding将尺寸撑开,在disabled状态自定义颜色和交互方式。

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

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

JavaScript逻辑

需要用到的元素有两个按钮、进度条和步骤结点。同时全局维护一个变量记录当前进度的位置。

const prev = document.getElementById('prev');
const next = document.getElementById('next');
const progress = document.getElementById('progress');
const nodes = document.querySelectorAll('.node');

let currentActive = 0;

根据前面的思路,两个按钮触发的公共事件主要有三:
1. 根据当前位置,判断按钮是否还可用。
2. 进度前的结点设置active类,进度后的移除active类。
3. 对进度条的样式宽度重新计算。

const update = () => {
    if(currentActive <= 0){
        prev.setAttribute('disabled', true);
    }else if(currentActive >= nodes.length-1){
        next.setAttribute('disabled', true);
    }else{
        prev.removeAttribute('disabled');
        next.removeAttribute('disabled');
    }

    nodes.forEach((node, index) => {
        if(currentActive >= index){
            node.classList.add('active');
            return;
        }
        node.classList.remove('active');
    });

    progress.style.width = currentActive/(nodes.length-1) * 100 + '%';
}

接着分别给两个按钮绑定点击事件,主要是控制全局变量的增加或减小,对于边界的判定因为之后设置disabled所以也可以不写,不过写上可以说是防抖设计了。

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

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

   if(currentActive >= nodes.length){
       currentActive = nodes.length-1;
   }
   update();
});

总结

  1. 进度条可以使用绝对定位,宽度100%+低层级来实现
  2. text-align不仅作用于文本,对行内元素均有效
  3. before伪类可以减少HTML元素数量,但是需要定义content
  4. z-index相同的情况下,DOM流靠后的元素会覆盖掉前面的元素

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/415904.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解计算机系统第九章知识点总结

第九章 一些术语 PA(physical address)&#xff1a;物理地址VA(virtual address)&#xff1a;虚拟地址MMU(memory management unit)&#xff1a;内存管理单元VP(virtual page)&#xff1a;虚拟页PP(physical page)&#xff1a;物理页/页帧SRAM&#xff1a;表示位于CPU和主存之…

详解Spring事务

目录 1.声明式事务 1.1.概述 1.2.使用 1.2.1.建表 1.2.2.maven依赖 1.2.3.配置 1.2.4.业务 1.2.5.测试 2.事务的传播行为 1.声明式事务 1.1.概述 spring中事务分为两种&#xff1a; 1.编程式事务&#xff0c;通过写代码来实现&#xff0c;每一步。 2.声明式事务&am…

华为手表开发:WATCH 3 Pro(15)传感器订阅加速度计

华为手表开发&#xff1a;WATCH 3 Pro&#xff08;15&#xff09;传感器订阅加速度计初环境与设备加速度传感器介绍与说明鸿蒙开发文件夹&#xff1a;文件重点新增展示的文本标记index.hmlindex.cssindex.js初 希望能写一些简单的教程和案例分享给需要的人 鸿蒙可穿戴开发 环…

Elasticsearch:索引状态是红色还是黄色?为什么?

在我之前文章 “Elasticsearch&#xff1a;如何调试集群状态 - 定位错误信息” 中&#xff0c;我有详细介绍如何调试集群状态。在今天的文章中&#xff0c;我将详细介绍如何故障排除和修复索引状态。 Elasticsearch 是一个伟大而强大的系统&#xff0c;特别是创建一个可扩展性极…

C++、STL标准模板库和泛型编程 ——关联式容器 (侯捷)

C、STL标准模板库和泛型编程——关联式容器 &#xff08;侯捷&#xff09;&#xff08; 持续更新&#xff01;&#xff01;&#xff01;&#xff09; 关联式容器rb_tree 容器set、multiset 容器map、multimap容器C、STL标准模板库和泛型编程——序列式容器 &#xff08;侯捷&am…

go+vue——go入门

govue技术选择入坑理由需要搭建前后端&#xff0c;Java 0 基础 &#xff0c;环境容易出现问题&#xff1b;GO上手快&#xff0c;问题少推荐&#xff1a;【七米】代码博客搭建Go语言开发环境下载 并 安装检查是否安装好&#xff1f;GOPROXY 非常重要&#xff08;帮你下载国外、G…

分布式锁Redision

目录 1.ab工具(压测工具)的安装 2.前置 3.优化 3.1synchronized修饰代码方法/代码块 3.2分布式锁事务的解决方案 3.3Redis实现锁问题 3.3.1 set ex方式 3.3.2 set ex方式设置过期时间 3.3.3单redis结点的解决UUID和LUA脚本 3.3.4redission解决分布式锁 4.Redission解…

数据结构:顺序表

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下数据结构方面有关顺序表的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C语言专栏&#xff1a;C语言&#xff1a;从入门…

阿里的Leader为什么牛逼?秘密都在“三板斧”里...

许多人都觉得&#xff0c;啊里出来的Leader&#xff0c;做事情都很有方法、有套路、有结果&#xff0c;秘密究竟在哪里&#xff1f;其实一个人的牛逼&#xff0c;首先是方法论的牛逼。本文就来聊聊&#xff0c;阿里Leader们都要学习的管理方法论&#xff0c;俗称阿里“三板斧”…

《MySQL系列-InnoDB引擎37》索引与算法-全文检索

全文检索 1 概述 对于B树的特点&#xff0c;可以通过索引字段的前缀进行查找。例如如下的查询方式是支持B树索引的,只要name字段添加了B树索引&#xff0c;就可以利用索引快速查找以XXX开头的名称。 select * from table where name like XXX%; 而如下这种情况不适合私有B索…

BUUCTF-sql注入联合查询的创建虚拟表-词频-steghide的使用

第七周第三次 目录 WEB [GXYCTF2019]BabySQli [GXYCTF2019]BabyUpload Crypto 世上无难事 old-fashion ​Misc 面具下的flag 九连环 WEB [GXYCTF2019]BabySQli 这是一道很新的题目 我们打开环境 发现登入注册界面 先看看源码有没有提示 发现有一个 php文件 进入…

Spark 对hadoopnamenode-log文件进行数据清洗并存入mysql数据库

一.查找需要清洗的文件 1.1查看hadoopnamenode-log文件位置 1.2 开启Hadoop集群和Hive元数据、Hive远程连接 具体如何开启可以看我之前的文章&#xff1a;(10条消息) SparkSQL-liunx系统Spark连接Hive_难以言喻wyy的博客-CSDN博客 1.3 将这个文件传入到hdfs中&#xff1a; hd…

OpenAI Translator | 基于ChatGPT API全局翻译润色解析及ORC上传图像翻译插件

简介 OpenAI Translator&#xff0c;一款基于 ChatGPT API 的划词翻译的浏览器插件和跨平台桌面端应用&#xff0c;使用 ChatGPT API 进行划词翻译和文本润色&#xff0c;借助了 ChatGPT 强大的翻译能力&#xff0c;帮助用户更流畅地阅读外语和编辑外语&#xff0c;允许跨 55 …

Qt音视频开发35-左右通道音量计算和音量不同范围值的转换

一、前言 视频文件一般会有两个声音通道及左右声道&#xff0c;值有时候一样有时候不一样&#xff0c;很多场景下我们需要对其分开计算不同的音量值&#xff0c;在QAudioFormat中可以获取具体有几个通道&#xff0c;如果是一个通道&#xff0c;则左右通道值设定一样&#xff0…

【时序数据库】时间序列数据和MongoDB第三部分-查询、分析和呈现时间序列数据...

在《时间序列数据和MongoDB:第1部分-简介》「时序数据库」时间序列数据与MongoDB&#xff1a;第一部分-简介中&#xff0c;我们回顾了理解数据库的查询访问模式需要询问的关键问题。在《时间序列数据和MongoDB:第2部分-模式设计最佳实践》「时序数据库」时序数据库和MongoDB第二…

Java实验课的学习笔记(二)类的简单使用

本文章就讲的是很基础的类的使用 重点大概就是类的构造函数以及一些很基础的东西。 实验内容是些老生常谈的东西&#xff0c;Complex类&#xff0c;在当初学C面向对象的时候也是这个样子展开的。 内容如以下&#xff1a; public class Complex {float real;float imag;public…

APK瘦身

先看下APK打包流程&#xff1a;APK打包流程_贺兰猪的博客-CSDN博客 知道了APK打包流程后想要瘦身&#xff0c;其实无非就是把整个APK的一些文件进行一个瘦身。 看下apk的这个文件。包括class、资源&#xff0c;资源生成arsc(资源映射表)&#xff0c;manifest清单&#xff0c;…

快排(非递归)及计数排序算法

都学了递归版的快速排序为何还要再学非递归实现&#xff1f;由于在递归过程中&#xff0c;如果数据量过大&#xff0c;那么实现时容易导致栈溢出&#xff0c;虽然代码没有问题&#xff0c;但是就是会崩&#xff0c;因此要将其改为非递归来实现 文章目录一、快速排序&#xff08…

如何使用Mac远程控制Windows电脑?

在你开始之前&#xff0c;设置您要远程处理的 Windows 计算机。 先安装 Microsoft Remote Desktop。 您可以在“应用程序”文件夹中检查它。 如果在个人计算机上安装&#xff0c;请转到 Apple App Store 并下载 Microsoft Remote Desktop。 如果在 TXST 计算机上安装&#xff0…

【C语言】递归解决经典题目(汉诺塔问题、青蛙跳台阶问题)

简单不先于复杂&#xff0c;而是在复杂之后。 目录 1. 汉诺塔问题 1.1 简介及思路 1.2 代码实现 2. 青蛙跳台阶问题 2.1 简介及思路 2.2 代码实现 1. 汉诺塔问题 1.1 简介及思路 汉诺塔问题是一种经典的递归问题&#xff0c;起源于印度传说中的塔 of Brahma。问题描…