最近接手个新项目,项目技术原型让用jQuery来实现,系统框架也是用Jquery+layui来搭建的,作为组件库使用习惯了,好久没自己手写实现UI交互效果了,还好不算太费劲,记录一下子
效果这样子:
css:
/* styles.css */
body {
font-family: Arial, sans-serif;
background-color: #ffffff;
padding: 20px;
}
.steps {
display: flex;
padding: 20px;
justify-content: space-between;
margin-bottom: 20px;
position: relative;
background-color: #faf8f8;
}
.step {
position: relative;
flex: 1;
text-align: center;
cursor: pointer;
z-index: 5;
}
.step-circle {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #ebeef5;
color: #909399;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
margin: 0 auto;
border: 1px solid #ebeef5;
}
.step-title {
font-size: 18px;
color: #909399;
display: flex;
align-items: center;
justify-content: center;
margin-top: 12px;
}
.step-sub-title {
font-size: 14px;
color: #909399;
/* display: flex;
align-items: center;
justify-content: center; */
}
.step.active .step-circle {
background-color: #122e9d;
color: #fff;
border-color: #122e9d;
}
.step.active .step-title {
color: #0c0d0d;
}
.step.completed .step-circle {
background-color: #0b0c0d;
color: #fff;
border-color: #0b0c0d;
}
.step.completed .step-title {
color: #616161;
}
/* 使用伪元素 ::after 创建横线 */
.step:not(:first-child)::after {
content: '';
position: absolute;
top: 15px;
right: 60%;
width: 80%;
height: 1px;
background-color: #676666;
z-index: -1;
}
/* 确保当前步骤的横线颜色正确 */
.step.completed::after {
background-color: #0b1014;
}
.step.active::after {
background-color: #0b1014;
}
.step-content {
width: 100%;
height: 680px;
overflow: scroll; /* 或者 overflow: auto */
padding-bottom: 30px; /* 确保内容不会被固定在底部的按钮遮挡 */
}
/* 隐藏滚动条(适用于 WebKit 浏览器) */
.step-content::-webkit-scrollbar {
display: none;
}
.step-pane {
display: none;
}
.step-pane.active {
display: block;
}
.step-controls {
position: fixed;
width: 94%;
bottom: 0;
right: 20px;
padding: 10px;
text-align: end;
border-top: 1px solid #ebeef5;
}
.step-button {
padding: 10px 20px;
width: 130px;
margin: 0 10px;
border: none;
border-radius: 4px;
cursor: pointer;
background-color: #185491;
color: #fff;
}
.step-button.prev {
background-color: #ebeef5;
color: #909399;
}
.step-button.prev:hover {
background-color: #d3dce6;
}
.step-button.next:hover {
background-color: #1b5d9f;
}
js:
// script.js
document.addEventListener('DOMContentLoaded', function () {
let totalSteps = 4; // 可以从外部传入
let currentStep = 1; // 可以从外部传入
function showStep(step, total) {
document.querySelectorAll('.step').forEach(stepElement => {
const stepNumber = parseInt(stepElement.getAttribute('data-step'));
if (stepNumber < step) {
stepElement.classList.add('completed');
stepElement.classList.remove('active');
} else if (stepNumber === step) {
stepElement.classList.add('active');
stepElement.classList.remove('completed');
} else {
stepElement.classList.remove('active', 'completed');
}
});
// 切换 step-pane 的内容
document.querySelectorAll('.step-pane').forEach(pane => {
pane.classList.remove('active');
if (parseInt(pane.getAttribute('data-step')) === step) {
pane.classList.add('active');
}
});
// 控制上一步按钮的显示与隐藏
const prevButton = document.querySelector('.step-button.prev');
if (step === 1) {
prevButton.style.display = 'none';
} else {
prevButton.style.display = 'inline-block';
}
// 控制下一步按钮的显示与隐藏
const nextButton = document.querySelector('.step-button.next');
if (step === total) {
nextButton.style.display = 'none';
} else {
nextButton.style.display = 'inline-block';
}
}
function nextStep(currentStep, totalSteps) {
if (currentStep < totalSteps) {
currentStep++;
showStep(currentStep, totalSteps);
}
return currentStep;
}
function prevStep(currentStep) {
if (currentStep > 1) {
currentStep--;
showStep(currentStep, totalSteps);
}
return currentStep;
}
// 新增的方法:跳转到指定步骤
function goToStep(step, totalSteps) {
if (step >= 1 && step <= totalSteps) {
currentStep = step;
showStep(currentStep, totalSteps);
} else {
console.warn('Invalid step number');
}
return currentStep;
}
// 初始化显示第一步
function initStep(step, total) {
totalSteps = parseInt(total);
currentStep = parseInt(step);
showStep(currentStep, totalSteps);
}
window.initStep = initStep;
// 添加按钮点击事件监听器
document.querySelector('.step-button.prev').addEventListener('click', function (e) {
e.preventDefault(); // 阻止默认行为
currentStep = prevStep(currentStep, totalSteps);
});
document.querySelector('.step-button.next').addEventListener('click', function (e) {
e.preventDefault(); // 阻止默认行为
currentStep = nextStep(currentStep, totalSteps);
});
// 为所有 step 元素添加点击事件监听器
document.querySelectorAll('.step').forEach(step => {
step.addEventListener('click', function () {
const stepNumber = parseInt(this.getAttribute('data-step'));
currentStep = goToStep(stepNumber, totalSteps);
});
});
});
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Element UI Steps Example</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div style="width: 90vw; height: 90vh">
<div class="steps">
<div class="step" data-step="1">
<div class="step-circle">1</div>
<div class="step-title">油品出厂质量合格证</div>
<div class="step-sub-title">Product Certificate of Quality</div>
</div>
<div class="step" data-step="2">
<div class="step-circle">2</div>
<div class="step-title">中转油库到货品质检查记录</div>
<div class="step-sub-title">Intermediate Oil Depot Quality Control Records during Fuel Receipt</div>
</div>
<div class="step" data-step="3">
<div class="step-circle">3</div>
<div class="step-title">中转油库收油品质检查记录</div>
<div class="step-sub-title">Intermediate Oil Depot Quality Control Records Fuel Receipt</div>
</div>
<div class="step" data-step="4">
<div class="step-circle">4</div>
<div class="step-title">中转油库重新评定检验报告</div>
<div class="step-sub-title">Intermediate Oil Depot Recertification Test Report</div>
</div>
<div class="step" data-step="5">
<div class="step-circle">5</div>
<div class="step-title">中转油库发货品质检查记录</div>
<div class="step-sub-title">Intermediate Oil Depot Release Certificate</div>
</div>
<div class="step" data-step="6">
<div class="step-circle">6</div>
<div class="step-title">油品接收条件检查</div>
<div class="step-sub-title">Product Receipt Condition Check</div>
</div>
</div>
<div class="step-content">
<div class="step-pane active" data-step="1">
<!-- 步骤1内容 -->
111
</div>
<div class="step-pane" data-step="2">
<!-- 步骤2内容 -->
2222
</div>
<div class="step-pane" data-step="3">
<!-- 步骤3内容 -->
333
</div>
<div class="step-pane" data-step="4">
<!-- 步骤4内容 -->
444
</div>
<div class="step-pane" data-step="5">
<!-- 步骤4内容 -->
555
</div>
<div class="step-pane" data-step="6">
<!-- 步骤4内容 -->
666
</div>
</div>
<div class="step-controls">
<button class="step-button prev">上一步</button>
<button class="step-button next">下一步</button>
</div>
</div>
<script src="./script.js"></script>
<script type="text/javascript">
window.onload = function () {
// 初始化显示第一步
initStep(1, 6);
};
</script>
</body>
</html>