里程碑式进度条交互与布局问题求助
Hey there! Let's work through your two problems step by step: making milestones stay red after clicking, and fixing the overflowing milestone dots when moving the progress bar to the first column.
1. Keeping Milestones Red After Click (No Per-Div onclick Needed)
Your original code uses the :active pseudo-class, which only applies while the mouse button is held down. To make the red state stick, we'll switch to a custom .active class and tweak your existing JavaScript logic to manage it properly—no need to add onclick to each div, your current loop approach is perfect!
Key Fixes Here:
- Replace the CSS
:activerule with.activefor persistent styling - Keep your batch click handler logic, it already handles activating the right milestones
2. Fixing Overflowing Milestone Dots
When you moved the progress bar into a col-9 container, the absolute-positioned dots (especially the last one at left: 100%) overflowed because they were positioned relative to the page instead of the progress bar. We'll fix this by:
- Setting
position: relativeon the.progresscontainer so dots are contained within it - Adjusting the last dot's position to
calc(100% - 10px)(subtract half the dot's width to keep it inside the column)
Updated Full Code
JavaScript
var mileStones = Array.from(document.querySelectorAll('.primary-color')); mileStones.forEach(elem => { elem.addEventListener('click', function() { // More flexible than direct onclick assignment const current = this; let flag = false; document.getElementById('pp').style.width = current.dataset.width + '%'; mileStones.forEach(elem => { elem.classList.add('active'); if (flag) elem.classList.remove('active'); if (current.id === elem.id) flag = true; }); }); });
CSS
.progress { width: 100%; height: 6px; margin-top: 50px; position: relative; /* Contains absolute-positioned dots */ overflow: visible; /* Ensures dots aren't clipped */ } .progress-bar { width: 0%; /* Match initial milestone state */ background-color: #00A2DB; } #one, #two, #three, #four, #five { position: absolute; margin-top: -8px; z-index: 1; height: 20px; width: 20px; border-radius: 25px; cursor: pointer; /* Visual cue that milestones are clickable */ } #one, .percent { left: 0%; } #two, .percent1 { left: 25%; } #three, .percent2 { left: 50%; } #four, .percent3 { left: 75%; } #five, .percent4 { left: calc(100% - 10px); /* Keep last dot inside container */ } .primary-color { background-color: pink; } .primary-color.active { /* Persistent red state after click */ background-color: red; }
HTML
<head> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"> </head> <div class="row"> <div class="col-9"> <p>Business case completion:</p> <div class="progress" id="progress"> <div class="primary-color active" id="one" data-width="0"></div> <!-- Initial active state for first milestone --> <div class="primary-color" id="two" data-width="25"></div> <div class="primary-color" id="three" data-width="50"></div> <div class="primary-color" id="four" data-width="75"></div> <div class="primary-color" id="five" data-width="100"></div> <div class="progress-bar" id="pp" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div> <!-- Sync aria value with initial progress --> </div> </div> <div class="col-3 align-self-end"> <p class="primary1"> ID 453</p> </div> </div>
Quick Extra Touches:
- Switched to
addEventListenerfor better flexibility (supports multiple listeners later if needed) - Added
cursor: pointerto milestones so users know they're interactive - Set initial
.activeclass on the first milestone to match the 0% progress bar - Updated
aria-valuenowto stay in sync with the initial state for accessibility
内容的提问来源于stack exchange,提问作者Keerthi Reddy Yeruva

