HTML5 进度条综合示例
1.基本进度条
2.计量条
3.自定义样式进度条
4.分段进度条
5.圆形进度条
6.动画效果进度条
7.文件上传进度模拟
8.测试列表
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 进度条综合示例</title>
<style>
/* 全局样式 */
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
/* 为悬浮导航留出空间 */
padding-top: 60px;
}
section {
margin-bottom: 40px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
background-color: #f9f9f9;
}
h2 {
color: #333;
border-bottom: 2px solid #4CAF50;
padding-bottom: 10px;
}
.control-panel {
margin: 15px 0;
padding: 10px;
background-color: #eee;
border-radius: 5px;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
transition: background-color 0.3s;
}
button:hover {
background-color: #45a049;
}
/* 基本进度条样式 */
#basic-progress-bar {
width: 300px;
height: 20px;
}
/* 计量条样式 */
#meter-bar {
width: 300px;
height: 25px;
}
/* 自定义样式进度条 */
#custom-progress-container {
width: 300px;
height: 20px;
background-color: #f1f1f1;
border-radius: 10px;
overflow: hidden;
margin: 10px 0;
}
#custom-progress-bar {
height: 100%;
background-color: #4CAF50;
width: 0%;
transition: width 0.3s;
text-align: center;
line-height: 20px;
color: white;
}
/* 分段进度条 */
#segmented-progress-container {
width: 300px;
height: 20px;
display: flex;
border-radius: 10px;
overflow: hidden;
margin: 10px 0;
}
.progress-segment {
height: 100%;
transition: flex-grow 0.5s;
}
#segment-1 {
background-color: #FF5252;
}
#segment-2 {
background-color: #FFD740;
}
#segment-3 {
background-color: #69F0AE;
}
/* 圆形进度条 */
#circular-progress-container {
position: relative;
width: 100px;
height: 100px;
margin: 10px 0;
}
.circle-bg {
fill: none;
stroke: #f1f1f1;
stroke-width: 8;
}
.circle-fill {
fill: none;
stroke: #4CAF50;
stroke-width: 8;
stroke-linecap: round;
stroke-dasharray: 283;
stroke-dashoffset: 283;
transform-origin: 50% 50%;
transform: rotate(-90deg);
transition: stroke-dashoffset 0.5s;
}
#circular-progress-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 20px;
font-weight: bold;
}
/* 动画进度条 */
#animated-progress-container {
width: 300px;
height: 20px;
background-color: #f1f1f1;
border-radius: 10px;
overflow: hidden;
position: relative;
margin: 10px 0;
}
#animated-progress-bar {
height: 100%;
background: linear-gradient(90deg, #4CAF50, #8BC34A);
width: 0%;
position: relative;
animation: progressAnimation 2s infinite linear;
}
@keyframes progressAnimation {
0% {
background-position: 0% 50%;
}
100% {
background-position: 100% 50%;
}
}
/* 文件上传进度条 */
#upload-progress-bar {
width: 300px;
height: 20px;
margin: 10px 0;
}
/* 导航栏样式 */
nav {
background-color: #333;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
transition: all 0.3s;
}
nav a:hover {
background-color: #ddd;
color: black;
}
nav.collapsed {
width: 220px;
height: 54px;!important;
}
nav.vertical.collapsed {
width: 220px;
height: 54px;!important;
}
nav.vertical {
width: 220px;
height: 100vh;
top: 0;
}
nav.vertical.left {
left: 0;
right: auto;
}
nav.vertical.right {
right: 0;
left: auto;
}
nav a {
float: left;
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
white-space: nowrap;
transition: all 0.3s;
}
nav.collapsed a {
padding: 14px 0;
width: 50px;
text-indent: -9999px;
}
nav.vertical a {
float: none;
width: 100%;
padding: 14px 0;
}
nav.vertical .toggle-div {
width: 200px;
height: 50px;
}
#toggle-collapse {
position: absolute;
top: 8px;
right: 10px;
background-color: #555;
color: white;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
}
#toggle-position {
position: absolute;
top: 8px;
right: 100px;
background-color: #555;
color: white;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
}
/* 置顶按钮样式 */
#top-button {
display: none;
position: fixed;
bottom: 20px;
right: 20px;
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
z-index: 100;
}
#top-button:hover {
background-color: #45a049;
}
/* 右下侧悬浮显示菜单 */
.right-menu-ul {
list-style-type: decimal;
/* display: none; */
position: fixed;
bottom: 50px;
right: 20px;
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 30px;
border-radius: 4px;
cursor: pointer;
z-index: 100;
}
.right-menu-ul a {
float: left;
display: block;
color: white;
text-align: center;
/*padding: 14px 16px;*/
text-decoration: none;
}
.right-menu-ul a:hover{
background-color: #ddd;
color: black;
}
.right-menu-ul li:hover{
background-color: #ddd;
color: black;
}
</style>
</head>
<body>
<!-- 导航栏 -->
<nav id="nav">
<div class="toggle-div">
<button id="toggle-collapse">折叠</button>
<button id="toggle-position">切换位置</button>
</div>
<a href="#basic-progress-section">基本进度条</a>
<a href="#meter-section">计量条</a>
<a href="#custom-progress-section">自定义样式进度条</a>
<a href="#segmented-progress-section">分段进度条</a>
<a href="#circular-progress-section">圆形进度条</a>
<a href="#animated-progress-section">动画效果进度条</a>
<a href="#upload-progress-section">文件上传进度模拟</a>
<a href="#test-section">测试列表</a>
</nav>
<h1>HTML5 进度条综合示例</h1>
<!-- 基本进度条 -->
<section id="basic-progress-section">
<h2>1. 基本进度条 (progress元素)</h2>
<p>HTML5原生提供的progress元素,适用于表示任务完成进度。</p>
<div class="control-panel">
<label>总进度: <input type="number" id="basic-max" value="100" min="1"></label>
<label>当前进度: <input type="number" id="basic-value" value="0" min="0"></label>
<label>更新间隔(ms): <input type="number" id="basic-interval" value="500" min="100"></label>
<button id="basic-start">开始</button>
<button id="basic-reset">重置</button>
</div>
<!-- 不确定的进度 -->
<p>不确定的进度(不指定value):</p>
<progress id="basic-indeterminate-progress"></progress>
<!-- 确定的进度 -->
<p>确定的进度:</p>
<progress id="basic-progress-bar" value="0" max="100"></progress>
</section>
<!-- 计量条 -->
<section id="meter-section">
<h2>2. 计量条 (meter元素)</h2>
<p>HTML5的meter元素,适用于表示度量值,可以设置高/低/最佳阈值。</p>
<div class="control-panel">
<label>最小值: <input type="number" id="meter-min" value="0"></label>
<label>最大值: <input type="number" id="meter-max" value="100"></label>
<label>低阈值: <input type="number" id="meter-low" value="30"></label>
<label>高阈值: <input type="number" id="meter-high" value="80"></label>
<label>最佳值: <input type="number" id="meter-optimum" value="90"></label>
<label>当前值: <input type="number" id="meter-value" value="0"></label>
<label>更新间隔(ms): <input type="number" id="meter-interval" value="500" min="100"></label>
<button id="meter-start">开始</button>
<button id="meter-reset">重置</button>
</div>
<meter id="meter-bar" min="0" max="100" low="30" high="80" optimum="90" value="0"></meter>
</section>
<!-- 自定义样式进度条 -->
<section id="custom-progress-section">
<h2>3. 自定义样式进度条</h2>
<p>使用div和CSS自定义样式的进度条,提供更大的灵活性。</p>
<div class="control-panel">
<label>总进度: <input type="number" id="custom-max" value="100" min="1"></label>
<label>当前进度: <input type="number" id="custom-value" value="0" min="0"></label>
<label>更新间隔(ms): <input type="number" id="custom-interval" value="500" min="100"></label>
<button id="custom-start">开始</button>
<button id="custom-reset">重置</button>
</div>
<div id="custom-progress-container">
<div id="custom-progress-bar">0%</div>
</div>
</section>
<!-- 分段进度条 -->
<section id="segmented-progress-section">
<h2>4. 分段进度条</h2>
<p>将进度分为多个部分,每部分可以有不同的样式和意义。</p>
<div class="control-panel">
<label>段1比例: <input type="number" id="segment-1-value" value="30" min="0"></label>
<label>段2比例: <input type="number" id="segment-2-value" value="40" min="0"></label>
<label>段3比例: <input type="number" id="segment-3-value" value="30" min="0"></label>
<label>动画时间(ms): <input type="number" id="segment-animation-time" value="1000" min="100"></label>
<button id="segment-update">更新</button>
<button id="segment-reset">重置</button>
</div>
<div id="segmented-progress-container">
<div id="segment-1" class="progress-segment" style="flex-grow: 0;"></div>
<div id="segment-2" class="progress-segment" style="flex-grow: 0;"></div>
<div id="segment-3" class="progress-segment" style="flex-grow: 0;"></div>
</div>
</section>
<!-- 圆形进度条 -->
<section id="circular-progress-section">
<h2>5. 圆形进度条</h2>
<p>使用SVG和CSS创建的圆形进度条,适合需要更视觉化展示的场景。</p>
<div class="control-panel">
<label>总进度: <input type="number" id="circular-max" value="100" min="1"></label>
<label>当前进度: <input type="number" id="circular-value" value="0" min="0"></label>
<label>更新间隔(ms): <input type="number" id="circular-interval" value="300" min="100"></label>
<button id="circular-start">开始</button>
<button id="circular-reset">重置</button>
</div>
<div id="circular-progress-container">
<svg viewBox="0 0 100 100">
<circle class="circle-bg" cx="50" cy="50" r="45"></circle>
<circle id="circular-progress-fill" class="circle-fill" cx="50" cy="50" r="45"></circle>
</svg>
<div id="circular-progress-text">0%</div>
</div>
</section>
<!-- 动画进度条 -->
<section id="animated-progress-section">
<h2>6. 动画效果进度条</h2>
<p>带有动画效果的进度条,增强用户体验。</p>
<div class="control-panel">
<label>总进度: <input type="number" id="animated-max" value="100" min="1"></label>
<label>当前进度: <input type="number" id="animated-value" value="0" min="0"></label>
<label>更新间隔(ms): <input type="number" id="animated-interval" value="300" min="100"></label>
<button id="animated-start">开始</button>
<button id="animated-reset">重置</button>
</div>
<div id="animated-progress-container">
<div id="animated-progress-bar"></div>
</div>
</section>
<!-- 文件上传进度条 -->
<section id="upload-progress-section">
<h2>7. 文件上传进度模拟</h2>
<p>模拟文件上传过程的进度条。</p>
<div class="control-panel">
<label>上传时间(ms): <input type="number" id="upload-duration" value="5000" min="1000"></label>
<button id="upload-simulate">模拟上传</button>
<button id="upload-reset">重置</button>
</div>
<input type="file" id="file-input">
<progress id="upload-progress-bar" value="0" max="100"></progress>
<div id="upload-status">准备上传...</div>
</section>
<!-- 测试列表 -->
<section id="test-section">
<h2>8. 测试列表</h2>
<p>带有动画效果,增强用户体验。</p>
<div class="control-panel">
<label>请输入: <input type="text" id="test-1-value" value=""></label>
<button id="test-start">开始</button>
<button id="test-reset">重置</button>
</div>
<div id="temented-progress-container">
</div>
<script>
const test1Value = document.getElementById('test-1-value');
const startBtn = document.getElementById('test-start');
const resetBtn = document.getElementById('test-reset');
const testContainer = document.getElementById('temented-progress-container');
startBtn.addEventListener('click', function() {
testContainer.innerText = test1Value.value + " = " + eval(test1Value.value)
});
resetBtn.addEventListener('click', function() {
test1Value.value = "";
testContainer.innerText = "";
});
</script>
</section>
<!-- 置顶按钮 -->
<button id="top-button">返回顶部</button>
<!-- 右下侧悬浮显示菜单 -->
<ul class="right-menu-ul">
<li><a href="#basic-progress-section">基本进度条</a></li>
<li><a href="#meter-section">计量条</a></li>
<li><a href="#custom-progress-section">自定义样式进度条</a></li>
<li><a href="#segmented-progress-section">分段进度条</a></li>
<li><a href="#circular-progress-section">圆形进度条</a></li>
<li><a href="#animated-progress-section">动画效果进度条</a></li>
<li><a href="#upload-progress-section">文件上传进度模拟</a></li>
<li><a href="#test-section">测试列表</a></li>
</ul>
<script>
// 浏览器中的跨页面通信(一):Broadcast Channel
const bc = new BroadcastChannel('test_channel');
// 新消息绑定监听:
bc.onmessage = function(e) {
console.log(new Date + '\treceive:', e.data);
};
// 对于错误也可以绑定监听:
bc.onmessageerror = function(e) {
console.warn(new Date + '\terror:', e);
};
bc.postMessage('hello')
</script>
<script>
// 基本进度条控制
(function() {
const progressBar = document.getElementById('basic-progress-bar');
const startBtn = document.getElementById('basic-start');
const resetBtn = document.getElementById('basic-reset');
const maxInput = document.getElementById('basic-max');
const valueInput = document.getElementById('basic-value');
const intervalInput = document.getElementById('basic-interval');
let basicInterval;
startBtn.addEventListener('click', function() {
clearInterval(basicInterval);
const max = parseInt(maxInput.value);
const interval = parseInt(intervalInput.value);
let progress = parseInt(valueInput.value);
progressBar.max = max;
progressBar.value = progress;
basicInterval = setInterval(() => {
progress += 5;
if (progress > max) progress = max;
progressBar.value = progress;
valueInput.value = progress;
if (progress >= max) {
clearInterval(basicInterval);
}
}, interval);
});
resetBtn.addEventListener('click', function() {
clearInterval(basicInterval);
progressBar.value = 0;
valueInput.value = 0;
});
})();
// 计量条控制
(function() {
const meterBar = document.getElementById('meter-bar');
const startBtn = document.getElementById('meter-start');
const resetBtn = document.getElementById('meter-reset');
const minInput = document.getElementById('meter-min');
const maxInput = document.getElementById('meter-max');
const lowInput = document.getElementById('meter-low');
const highInput = document.getElementById('meter-high');
const optimumInput = document.getElementById('meter-optimum');
const valueInput = document.getElementById('meter-value');
const intervalInput = document.getElementById('meter-interval');
let meterInterval;
startBtn.addEventListener('click', function() {
clearInterval(meterInterval);
const min = parseInt(minInput.value);
const max = parseInt(maxInput.value);
const low = parseInt(lowInput.value);
const high = parseInt(highInput.value);
const optimum = parseInt(optimumInput.value);
const interval = parseInt(intervalInput.value);
let value = parseInt(valueInput.value);
meterBar.min = min;
meterBar.max = max;
meterBar.low = low;
meterBar.high = high;
meterBar.optimum = optimum;
meterBar.value = value;
meterInterval = setInterval(() => {
value += 5;
if (value > max) value = max;
meterBar.value = value;
valueInput.value = value;
if (value >= max) {
clearInterval(meterInterval);
}
}, interval);
});
resetBtn.addEventListener('click', function() {
clearInterval(meterInterval);
meterBar.value = 0;
valueInput.value = 0;
});
})();
// 自定义进度条控制
(function() {
const progressBar = document.getElementById('custom-progress-bar');
const startBtn = document.getElementById('custom-start');
const resetBtn = document.getElementById('custom-reset');
const maxInput = document.getElementById('custom-max');
const valueInput = document.getElementById('custom-value');
const intervalInput = document.getElementById('custom-interval');
let customInterval;
startBtn.addEventListener('click', function() {
clearInterval(customInterval);
const max = parseInt(maxInput.value);
const interval = parseInt(intervalInput.value);
let progress = parseInt(valueInput.value);
updateCustomProgress(progress, max);
customInterval = setInterval(() => {
progress += 5;
if (progress > max) progress = max;
updateCustomProgress(progress, max);
valueInput.value = progress;
if (progress >= max) {
clearInterval(customInterval);
}
}, interval);
});
resetBtn.addEventListener('click', function() {
clearInterval(customInterval);
updateCustomProgress(0, parseInt(maxInput.value));
valueInput.value = 0;
});
function updateCustomProgress(value, max) {
const percent = Math.round((value / max) * 100);
progressBar.style.width = percent + '%';
progressBar.textContent = percent + '%';
}
})();
// 分段进度条控制
(function() {
const segment1 = document.getElementById('segment-1');
const segment2 = document.getElementById('segment-2');
const segment3 = document.getElementById('segment-3');
const updateBtn = document.getElementById('segment-update');
const resetBtn = document.getElementById('segment-reset');
const value1Input = document.getElementById('segment-1-value');
const value2Input = document.getElementById('segment-2-value');
const value3Input = document.getElementById('segment-3-value');
const animationTimeInput = document.getElementById('segment-animation-time');
updateBtn.addEventListener('click', function() {
const value1 = parseInt(value1Input.value);
const value2 = parseInt(value2Input.value);
const value3 = parseInt(value3Input.value);
const total = value1 + value2 + value3;
if (total <= 0) return;
// 设置动画时间
segment1.style.transitionDuration = animationTimeInput.value + 'ms';
segment2.style.transitionDuration = animationTimeInput.value + 'ms';
segment3.style.transitionDuration = animationTimeInput.value + 'ms';
// 更新比例
segment1.style.flexGrow = value1;
segment2.style.flexGrow = value2;
segment3.style.flexGrow = value3;
});
resetBtn.addEventListener('click', function() {
segment1.style.flexGrow = 0;
segment2.style.flexGrow = 0;
segment3.style.flexGrow = 0;
value1Input.value = 30;
value2Input.value = 40;
value3Input.value = 30;
});
})();
// 圆形进度条控制
(function() {
const circleFill = document.getElementById('circular-progress-fill');
const circleText = document.getElementById('circular-progress-text');
const startBtn = document.getElementById('circular-start');
const resetBtn = document.getElementById('circular-reset');
const maxInput = document.getElementById('circular-max');
const valueInput = document.getElementById('circular-value');
const intervalInput = document.getElementById('circular-interval');
let circularInterval;
startBtn.addEventListener('click', function() {
clearInterval(circularInterval);
const max = parseInt(maxInput.value);
const interval = parseInt(intervalInput.value);
let progress = parseInt(valueInput.value);
updateCircularProgress(progress, max);
circularInterval = setInterval(() => {
progress += 5;
if (progress > max) progress = max;
updateCircularProgress(progress, max);
valueInput.value = progress;
if (progress >= max) {
clearInterval(circularInterval);
}
}, interval);
});
resetBtn.addEventListener('click', function() {
clearInterval(circularInterval);
updateCircularProgress(0, parseInt(maxInput.value));
valueInput.value = 0;
});
function updateCircularProgress(value, max) {
const percent = Math.round((value / max) * 100);
const offset = 283 - (283 * percent / 100);
circleFill.style.strokeDashoffset = offset;
circleText.textContent = percent + '%';
}
})();
// 动画进度条控制
(function() {
const progressBar = document.getElementById('animated-progress-bar');
const startBtn = document.getElementById('animated-start');
const resetBtn = document.getElementById('animated-reset');
const maxInput = document.getElementById('animated-max');
const valueInput = document.getElementById('animated-value');
const intervalInput = document.getElementById('animated-interval');
let animatedInterval;
startBtn.addEventListener('click', function() {
clearInterval(animatedInterval);
const max = parseInt(maxInput.value);
const interval = parseInt(intervalInput.value);
let progress = parseInt(valueInput.value);
updateAnimatedProgress(progress, max);
animatedInterval = setInterval(() => {
progress += 5;
if (progress > max) progress = max;
updateAnimatedProgress(progress, max);
valueInput.value = progress;
if (progress >= max) {
clearInterval(animatedInterval);
}
}, interval);
});
resetBtn.addEventListener('click', function() {
clearInterval(animatedInterval);
updateAnimatedProgress(0, parseInt(maxInput.value));
valueInput.value = 0;
});
function updateAnimatedProgress(value, max) {
const percent = Math.round((value / max) * 100);
progressBar.style.width = percent + '%';
}
})();
// 文件上传进度模拟
(function() {
const fileInput = document.getElementById('file-input');
const progressBar = document.getElementById('upload-progress-bar');
const statusDiv = document.getElementById('upload-status');
const simulateBtn = document.getElementById('upload-simulate');
const resetBtn = document.getElementById('upload-reset');
const durationInput = document.getElementById('upload-duration');
let uploadInterval;
simulateBtn.addEventListener('click', function() {
clearInterval(uploadInterval);
const duration = parseInt(durationInput.value);
const steps = 20;
const interval = duration / steps;
let progress = 0;
statusDiv.textContent = '上传中: 模拟文件.txt';
progressBar.value = 0;
uploadInterval = setInterval(() => {
progress += (100 / steps);
if (progress > 100) progress = 100;
progressBar.value = progress;
if (progress >= 100) {
clearInterval(uploadInterval);
statusDiv.textContent = '上传完成: 模拟文件.txt';
}
}, interval);
});
fileInput.addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
clearInterval(uploadInterval);
const duration = parseInt(durationInput.value);
const steps = 20;
const interval = duration / steps;
let progress = 0;
statusDiv.textContent = `上传中: ${file.name}`;
progressBar.value = 0;
uploadInterval = setInterval(() => {
progress += (100 / steps);
if (progress > 100) progress = 100;
progressBar.value = progress;
if (progress >= 100) {
clearInterval(uploadInterval);
statusDiv.textContent = `上传完成: ${file.name}`;
}
}, interval);
});
resetBtn.addEventListener('click', function() {
clearInterval(uploadInterval);
fileInput.value = '';
progressBar.value = 0;
statusDiv.textContent = '准备上传...';
});
})();
</script>
<script>
//右下侧悬浮显示菜单
const nav = document.getElementById('nav');
const toggleCollapse = document.getElementById('toggle-collapse');
const togglePosition = document.getElementById('toggle-position');
let isCollapsed = false;
let isVertical = false;
let isLeft = true;
toggleCollapse.addEventListener('click', function () {
if (isCollapsed) {
nav.classList.remove('collapsed');
toggleCollapse.textContent = '折叠';
} else {
nav.classList.add('collapsed');
toggleCollapse.textContent = '展开';
}
isCollapsed = !isCollapsed;
});
togglePosition.addEventListener('click', function () {
if (!isVertical) {
nav.classList.add('vertical');
nav.classList.add('left');
isVertical = true;
togglePosition.textContent = '切换到顶部';
} else {
if (isLeft) {
nav.classList.remove('vertical');
nav.classList.remove('left');
isVertical = false;
isLeft = true;
togglePosition.textContent = '切换到侧边';
}
/*if (isLeft) {
nav.classList.remove('left');
nav.classList.add('right');
isLeft = false;
} else {
nav.classList.remove('vertical');
nav.classList.remove('right');
isVertical = false;
isLeft = true;
togglePosition.textContent = '切换到侧边';
}*/
}
});
// 显示或隐藏置顶按钮
window.onscroll = function () {
var topButton = document.getElementById("top-button");
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
topButton.style.display = "block";
} else {
topButton.style.display = "none";
}
};
// 点击置顶按钮滚动到页面顶部
document.getElementById("top-button").addEventListener("click", function () {
document.body.scrollTop = 0; // 对于 Safari
document.documentElement.scrollTop = 0; // 对于 Chrome、Firefox、IE 和 Opera
});
</script>
</body>
</html>