这是为您生成的一个可直接运行的HTML文档,它实现了一个带有动画效果和交互控制的进度条案例。

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">进度条 · 灵活动画案例</title>
<!-- 使用优雅柔和的字体 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: linear-gradient(145deg, #f9fafc 0%, #eef2f7 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
padding: 1.5rem;
}
.card {
max-width: 720px;
width: 100%;
background: rgba(255, 255, 255, 0.75);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
box-shadow: 0 25px 45px -12px rgba(0, 20, 30, 0.15), 0 2px 8px rgba(0,0,0,0.02);
border: 1px solid rgba(255, 255, 255, 0.6);
border-radius: 36px;
padding: 2rem 2rem 2.2rem;
transition: all 0.2s ease;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 1.2rem;
flex-wrap: wrap;
gap: 0.75rem;
}
.card-header h2 {
font-weight: 600;
font-size: 1.5rem;
letter-spacing: -0.01em;
color: #1d2b3f;
display: flex;
align-items: center;
gap: 0.5rem;
}
.card-header h2 span {
background: #d9e2ef;
padding: 0.15rem 0.8rem;
border-radius: 100px;
font-size: 0.8rem;
font-weight: 500;
color: #24425c;
letter-spacing: 0.3px;
}
.percentage-badge {
background: #1d2b3f;
color: white;
padding: 0.4rem 1.2rem;
border-radius: 60px;
font-size: 1.4rem;
font-weight: 600;
box-shadow: 0 4px 12px rgba(29, 43, 63, 0.12);
letter-spacing: -0.5px;
line-height: 1;
display: flex;
align-items: center;
gap: 4px;
}
.percentage-badge small {
font-size: 0.9rem;
font-weight: 400;
opacity: 0.8;
}
/* 进度条主体 */
.progress-shell {
background: #e6ebf2;
border-radius: 200px;
height: 32px;
width: 100%;
padding: 4px;
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(255,255,255,0.6);
transition: box-shadow 0.1s;
margin-bottom: 1.8rem;
cursor: pointer;
position: relative;
}
.progress-bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #3b79c9, #62a0e8 70%, #77b7ff);
border-radius: 200px;
box-shadow: 0 2px 8px rgba(45, 110, 200, 0.25);
transition: width 0.25s cubic-bezier(0.2, 0.8, 0.3, 1);
position: relative;
overflow: hidden;
min-width: 8px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 2px;
}
/* 进度条光泽条纹效果 */
.progress-bar::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(180deg, rgba(255,255,255,0.45) 0%, rgba(255,255,255,0) 45%);
border-radius: inherit;
pointer-events: none;
}
/* 追踪点 (支持点击) */
.progress-rail {
position: relative;
margin-bottom: 1.4rem;
}
.track-dots {
display: flex;
justify-content: space-between;
font-size: 0.8rem;
font-weight: 500;
color: #4b5f75;
padding: 0 6px 0 2px;
margin-top: 6px;
user-select: none;
}
.track-dots span {
transition: color 0.2s, font-weight 0.2s;
background: transparent;
padding: 2px 8px;
border-radius: 40px;
}
.track-dots span.active {
color: #1d2b3f;
font-weight: 600;
background: rgba(29, 43, 63, 0.06);
}
/* 控制区域 */
.controls {
display: flex;
gap: 0.6rem;
flex-wrap: wrap;
align-items: center;
margin-top: 0.5rem;
}
button {
border: none;
background: white;
font-weight: 500;
font-size: 0.9rem;
padding: 0.65rem 1.4rem;
border-radius: 80px;
box-shadow: 0 4px 10px -4px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0,0,0,0.02);
display: inline-flex;
align-items: center;
gap: 6px;
color: #1d2b3f;
font-family: inherit;
letter-spacing: 0.2px;
transition: all 0.18s ease;
border: 1px solid rgba(255, 255, 255, 0.7);
cursor: pointer;
background: rgba(255,255,255,0.8);
backdrop-filter: blur(4px);
flex: 1 0 auto;
justify-content: center;
}
button:hover {
background: #ffffff;
box-shadow: 0 8px 16px -8px rgba(20, 80, 150, 0.2);
transform: translateY(-1px);
border-color: #c2d6ed;
}
button:active {
transform: translateY(1px);
box-shadow: inset 0 3px 8px rgba(0,0,0,0.04);
}
button.primary {
background: #1d2b3f;
color: white;
border: none;
}
button.primary:hover {
background: #2d3f57;
}
button.secondary {
background: rgba(29, 43, 63, 0.05);
}
.slider-box {
display: flex;
align-items: center;
gap: 0.8rem;
flex: 2 1 200px;
background: rgba(255,255,255,0.5);
padding: 0.2rem 0.6rem 0.2rem 1rem;
border-radius: 100px;
backdrop-filter: blur(4px);
border: 1px solid rgba(255,255,255,0.2);
}
.slider-box input[type="range"] {
flex: 1;
height: 6px;
-webkit-appearance: none;
background: #d2dbe7;
border-radius: 20px;
}
.slider-box input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
border: 2px solid #1d2b3f;
cursor: pointer;
transition: 0.1s;
}
.slider-box input[type="range"]::-moz-range-thumb {
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
border: 2px solid #1d2b3f;
cursor: pointer;
}
.slider-box span {
min-width: 3rem;
text-align: center;
font-weight: 600;
color: #1d2b3f;
font-size: 0.9rem;
}
.footer-actions {
display: flex;
justify-content: flex-end;
gap: 0.75rem;
margin-top: 0.5rem;
}
.footer-actions button {
flex: 0 1 auto;
padding: 0.5rem 1.2rem;
font-size: 0.85rem;
}
.label-hint {
color: #58718b;
font-size: 0.8rem;
margin-top: 0.8rem;
text-align: right;
opacity: 0.7;
letter-spacing: 0.3px;
}
/* 触摸友好 */
@media (max-width: 520px) {
.card {
padding: 1.5rem;
}
.controls button {
flex: 1 1 35%;
}
.slider-box {
flex: 1 1 100%;
order: 4;
}
}
</style>
</head>
<body>
<div class="card">
<!-- 头部 + 百分比 -->
<div class="card-header">
<h2>
⚡ 任务进度
<span>动态</span>
</h2>
<div class="percentage-badge" id="percentageDisplay">
0<small>%</small>
</div>
</div>
<!-- 进度条 (点击任意位置可按比例跳转) -->
<div class="progress-rail">
<div class="progress-shell" id="progressShell">
<div class="progress-bar" id="progressBar" style="width: 0%;"></div>
</div>
<!-- 刻度指示 -->
<div class="track-dots" id="trackDots">
<span data-value="0">0%</span>
<span data-value="25">25%</span>
<span data-value="50">50%</span>
<span data-value="75">75%</span>
<span data-value="100">100%</span>
</div>
</div>
<!-- 交互控件区 -->
<div class="controls">
<button class="secondary" id="decrBtn">− 10%</button>
<button class="primary" id="resetBtn">重置</button>
<button class="secondary" id="incrBtn">+ 10%</button>
<!-- 滑杆 -->
<div class="slider-box">
<input type="range" id="rangeSlider" min="0" max="100" value="0" step="1">
<span id="sliderValue">0%</span>
</div>
</div>
<!-- 底部辅助操作 -->
<div class="footer-actions">
<button id="loadAssistBtn">🎯 载入75%</button>
<button id="completeBtn">🚀 完成</button>
</div>
<div class="label-hint">
← 点击进度条快速定位 · 拖动滑杆精确控制 →
</div>
</div>
<script>
(function() {
// DOM 元素
const progressBar = document.getElementById('progressBar');
const percentageDisplay = document.getElementById('percentageDisplay');
const rangeSlider = document.getElementById('rangeSlider');
const sliderValue = document.getElementById('sliderValue');
const progressShell = document.getElementById('progressShell');
const trackDots = document.getElementById('trackDots');
const incrBtn = document.getElementById('incrBtn');
const decrBtn = document.getElementById('decrBtn');
const resetBtn = document.getElementById('resetBtn');
const loadAssistBtn = document.getElementById('loadAssistBtn');
const completeBtn = document.getElementById('completeBtn');
// 当前进度 (0-100)
let currentProgress = 0;
// 边界限制
function clamp(value, min = 0, max = 100) {
return Math.min(max, Math.max(min, value));
}
// 核心更新UI: 进度条宽度、百分比文本、滑杆、滑块数值、刻度高亮
function updateUI(progress) {
// 更新宽度
progressBar.style.width = progress + '%';
// 更新数字显示 (整数)
percentageDisplay.innerHTML = Math.round(progress) + '<small>%</small>';
// 更新滑杆值
rangeSlider.value = Math.round(progress);
sliderValue.textContent = Math.round(progress) + '%';
// 更新刻度高亮: 找到最近的刻度值
const dotSpans = trackDots.querySelectorAll('span[data-value]');
let activeValue = null;
let minDistance = Infinity;
dotSpans.forEach(span => {
const val = parseInt(span.dataset.value, 10);
const dist = Math.abs(progress - val);
if (dist < 20) { // 阈值 20,让当前进度附近的高亮更明显 (保留多区间)
if (dist < minDistance) {
minDistance = dist;
activeValue = span;
}
}
});
// 如果进度接近某个刻度 (25/50/75等) 高亮它,否则清空所有高亮
dotSpans.forEach(span => {
span.classList.remove('active');
});
if (activeValue && minDistance <= 10) { // 限制10以内高亮,更干净
activeValue.classList.add('active');
} else {
// 如果精确匹配不到高亮,但可能在25/50/75附近,取消高亮
}
}
// 统一设置进度并更新UI
function setProgress(newValue, updateSlider = true) {
currentProgress = clamp(Math.round(newValue));
updateUI(currentProgress);
}
// 增加/减少
function changeProgress(delta) {
setProgress(currentProgress + delta);
}
// 重置为0
function resetProgress() {
setProgress(0);
}
// 载入指定百分比 (示例: 75)
function loadPreset(value) {
setProgress(value);
}
// ---------- 进度条点击跳转 ----------
function handleProgressClick(event) {
const rect = progressShell.getBoundingClientRect();
const offsetX = event.clientX - rect.left;
const width = rect.width;
if (width <= 0) return;
// 计算百分比 (0-100)
let percent = (offsetX / width) * 100;
percent = clamp(Math.round(percent));
setProgress(percent);
}
// 绑定点击事件到进度条容器(点击空白/进度条都触发)
progressShell.addEventListener('click', handleProgressClick);
// 滑杆事件 (input)
rangeSlider.addEventListener('input', function(e) {
const val = parseInt(e.target.value, 10);
currentProgress = clamp(val);
updateUI(currentProgress);
});
// 按钮事件
incrBtn.addEventListener('click', () => changeProgress(10));
decrBtn.addEventListener('click', () => changeProgress(-10));
resetBtn.addEventListener('click', resetProgress);
loadAssistBtn.addEventListener('click', () => loadPreset(75));
completeBtn.addEventListener('click', () => loadPreset(100));
// 额外: 点击刻度也可以快速定位
trackDots.addEventListener('click', (e) => {
const span = e.target.closest('span[data-value]');
if (!span) return;
const val = parseInt(span.dataset.value, 10);
setProgress(val);
});
// 初始化显示
setProgress(0);
// 添加键盘无障碍: 可以按加减键(演示)
// 此时不加过多功能。
})();
</script>
</body>
</html>
进度条的核心交互与操作
您可以通过多种方式直观地控制进度,其核心交互逻辑清晰明了。
- 进度控制方式:您可以通过点击进度条任意位置直接跳转到对应百分比,或使用滑块进行精细调节,页面上的“+10%”、“-10%”、“重置”、“载入75%”和“完成”按钮则提供了快捷操作。
- 视觉反馈机制:进度条会以平滑动画过渡,且当进度接近25%、50%、75%、100%等刻度时,下方的刻度标记会高亮显示,帮助您快速定位进度。
- 状态同步显示:顶部的百分比数字、控制滑块旁的数值以及进度条本身会实时保持同步,让您对所控制的进度一目了然。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播