Bootstrap自定义滑块能否添加双滑块?需显示用户值与平均值
Great question! The native Bootstrap custom range component only supports a single thumb out of the box, so you’ll need to either extend it with custom CSS/JS or use a dual-slider approach with overlapping inputs. Let’s break down both options, tailored to your existing code:
Option 1: Overlay a Static Thumb for the Average Value
This approach keeps your existing user-editable slider and adds a static, styled element to mark the average value position.
Step 1: Fix & Update the showValues Function
First, correct the average calculation logic and track the current user’s input value:
function showValues(data) { var html = "", edit = false; var avgValue = 0; var userValue = 50; // Default to middle (no input) // Calculate average and find current user's value for (let i = 0; i < data.values.length; i++) { var valueObj = data.values[i]; avgValue += Number(valueObj.value); // Check if this is the current user's input if (valueObj._id === window.user._id) { edit = true; userValue = valueObj.value; } } // Final average calculation (fallback to 50 if no values exist) avgValue = data.values.length > 0 ? avgValue / data.values.length : 50; // Build slider container with user slider + average thumb html += '<span class="custom-range-container" onclick="setValue(this);" data-id="' + data._id + '">'; html += '<input type="range" class="custom-range user-slider" value="' + userValue + '" min="0" max="100" />'; html += '<span class="avg-thumb" style="left: ' + avgValue + '%"></span>'; html += '</span>'; return html; }
Step 2: Add Custom CSS for the Average Thumb
Style the static thumb to match Bootstrap’s design:
.custom-range-container { position: relative; display: block; width: 100%; padding: 0; } .user-slider { position: relative; z-index: 1; /* Ensure user slider is clickable */ } .avg-thumb { position: absolute; top: 50%; transform: translate(-50%, -50%); width: 1rem; height: 1rem; border-radius: 50%; background-color: #6c757d; /* Bootstrap secondary color for distinction */ z-index: 0; pointer-events: none; /* Prevent interference with user input */ }
Option 2: Use Two Overlapping Bootstrap Sliders
This method uses two standard Bootstrap range inputs stacked on top of each other—one for the user’s editable input, and a disabled one for the average value.
Step 1: Update showValues to Generate Dual Sliders
function showValues(data) { var html = "", edit = false; var avgValue = 0; var userValue = 50; for (let i = 0; i < data.values.length; i++) { var valueObj = data.values[i]; avgValue += Number(valueObj.value); if (valueObj._id === window.user._id) { edit = true; userValue = valueObj.value; } } avgValue = data.values.length > 0 ? avgValue / data.values.length : 50; // Build dual-slider container html += '<div class="dual-slider-container" onclick="setValue(this);" data-id="' + data._id + '">'; // Disabled slider for average (non-interactive) html += '<input type="range" class="custom-range avg-slider" value="' + avgValue + '" min="0" max="100" disabled />'; // Editable slider for user input html += '<input type="range" class="custom-range user-slider" value="' + userValue + '" min="0" max="100" />'; html += '</div>'; return html; }
Step 2: Add CSS to Stack Sliders
Make the sliders overlap and style their thumbs differently:
.dual-slider-container { position: relative; width: 100%; } .dual-slider-container input[type=range] { position: absolute; top: 0; left: 0; width: 100%; margin: 0; } /* Disable interaction with average slider */ .avg-slider { pointer-events: none; } /* Style average thumb to stand out */ .avg-slider::-webkit-slider-thumb { background-color: #6c757d; } .avg-slider::-moz-range-thumb { background-color: #6c757d; } .avg-slider::-ms-thumb { background-color: #6c757d; }
Update the setValue Function
After saving the user’s input via AJAX, you’ll need to refresh the slider data to update both the user’s value and the average. Add a call to re-fetch the data and re-render the slider in the AJAX success callback:
function setValue(self) { var _id = self.getAttribute("data-id"); // Target the user's editable slider specifically var value = self.querySelector('.user-slider').value; var ajax = new XMLHttpRequest(); ajax.open("POST", "/setValue", true); ajax.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { // Re-fetch data and re-render the slider (replace with your existing data fetch function) fetchSliderData(_id); } }; var formData = new FormData(); formData.append("accessToken", localStorage.getItem("accessToken")); formData.append("_id", _id); formData.append("value", value); ajax.send(formData); }
Key Notes
- You don’t need to replace Bootstrap entirely—both options extend the existing custom range component to meet your needs.
- The first option is lighter (fewer DOM elements), while the second uses native slider elements for consistent styling across browsers.
- Fixed your original average calculation bug (initial value was set to 50 instead of 0, and
data.value.lengthwas a typo fordata.values.length).
内容的提问来源于stack exchange,提问作者rawm

