问题描述
所以我找到了这个范围滑块,我试图让它变得动态。目前,JS 中有一些硬编码内容直接处理特定的 HTML 元素,我希望在我的 HTML 站点上有 10 个这些滑块都独立工作。我正在使用以下代码:https://codepen.io/mukealicious/pen/jWoeZY(也在下面)
const $element = $('input[type="range"]');
const $tooltip = $('#range-tooltip');
const sliderStates = [
{name: "low",tooltip: "Good.",range: _.range(80,100) },{name: "med",tooltip: "Okay.",range: _.range(101,149)},{name: "high",tooltip: "Bad.",range: [150] },];
var currentState;
var $handle;
$element
.rangeslider({
polyfill: false,onInit: function() {
$handle = $('.rangeslider__handle',this.$range);
updateHandle($handle[0],this.value);
updateState($handle[0],this.value);
}
})
.on('input',function() {
updateHandle($handle[0],this.value);
checkState($handle[0],this.value);
});
// Update the value inside the slider handle
function updateHandle(el,val) {
el.textContent = Math.round(0.25*val) + "€";
}
// Check if the slider state has changed
function checkState(el,val) {
// if the value does not fall in the range of the current state,update that shit.
if (!_.contains(currentState.range,parseInt(val))) {
updateState(el,val);
}
}
// Change the state of the slider
function updateState(el,val) {
for (var j = 0; j < sliderStates.length; j++){
if (_.contains(sliderStates[j].range,parseInt(val))) {
currentState = sliderStates[j];
// updateSlider();
}
}
// If the state is high,update the handle count to read 50+
if (currentState.name == "high") {
updateHandle($handle[0],"150");
}
// Update handle color
$handle
.removeClass (function (index,css) {
return (css.match (/(^|\s)js-\S+/g) || []).join(' ');
})
.addClass("js-" + currentState.name);
// Update tooltip
$tooltip.html(currentState.tooltip);
}
label {
display: block;
margin-bottom: 2.5em;
font-size: 13px;
font-weight: bold;
}
.rangeslider__tooltip {
display: block;
margin-top: 2.5em;
font-size: 12px;
color: #a59eb5;
max-width: max-content;
}
.rangeslider,input[type=range] {
max-width: 400px;
}
.rangeslider__handle {
border-radius: 22px;
line-height: 42px;
text-align: center;
font-weight: bold;
}
.rangeslider__handle:after {
background: 0;
}
.rangeslider,.rangeslider__fill {
display: block;
border-radius: 10px;
}
.rangeslider {
background: white;
background-image: linear-gradient(to right,#4bc67d 30%,#f1c40f 45%,#b94a48 99%);
position: relative;
}
.rangeslider--horizontal {
height: 7px;
width: 100%;
}
.rangeslider--vertical {
width: 20px;
min-height: 150px;
max-height: 100%;
}
.rangeslider--disabled {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
opacity: 0.4;
}
.rangeslider__fill {
position: absolute;
}
.rangeslider--horizontal .rangeslider__fill {
top: 0;
height: 100%;
}
.rangeslider--vertical .rangeslider__fill {
bottom: 0;
width: 100%;
}
.rangeslider__handle {
background: #e6e7ee;
border: 6px solid #4bc67d;
cursor: pointer;
display: inline-block;
width: 42px;
height: 42px;
position: absolute;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
font-size: small;
}
.rangeslider__handle.js-low {
border-color: #4bc67d;
}
.rangeslider__handle.js-med {
border-color: #f1c40f;
}
.rangeslider__handle.js-high {
border-color: #b94a48;
}
.rangeslider__handle:after {
content: "";
display: block;
width: 18px;
height: 18px;
margin: auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.rangeslider--horizontal .rangeslider__handle {
top: -20px;
touch-action: pan-y;
-ms-touch-action: pan-y;
}
.rangeslider--vertical .rangeslider__handle {
left: -10px;
touch-action: pan-x;
-ms-touch-action: pan-x;
}
input[type=range]:focus + .rangeslider .rangeslider__handle {
-moz-Box-shadow: 0 0 8px rgba(255,255,0.9);
-webkit-Box-shadow: 0 0 8px rgba(255,0.9);
Box-shadow: 0 0 8px rgba(255,0.9);
}
<!DOCTYPE html>
<html lang="en" >
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
</head>
<body>
<div class="main">
<input
type="range"
name="participants"
min="80"
max="150"
value="99"
oninput="showVal(this.value)"
onchange="showVal(this.value)"
>
<span class="rangeslider__tooltip" id ="range-tooltip"></span>
<div class="main">
<input
type="range"
name="participants"
min="80"
max="150"
value="99"
oninput="showVal(this.value)"
onchange="showVal(this.value)"
>
<span class="rangeslider__tooltip" id ="range-tooltip"></span>
<script>
function showVal(newVal){
console.log("updated");
</script>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://andreruffert.github.io/rangeslider.js/assets/rangeslider.js/dist/rangeslider.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore-min.js'></script>
</body>
</html>
我对 JS 进行了很多更改,但我的代码不断更改同一个 Rangeslider 的颜色,因为我做错了。你能帮忙提供任何提示吗?非常感谢
解决方法
由于 $element
现在有多个 input
元素...您必须使用 .each()
循环来实例化每个元素上的函数。
所以...我只是将整个内容移动到 .each()
循环中。没有更多变化。
对于工具提示,从全局变量中删除 const $tooltip = $("#range-tooltip");
...并使用 .siblings()
来定位正确的工具提示 span
。
const $element = $('input[type="range"]');
const sliderStates = [
{ name: "low",tooltip: "Good.",range: _.range(80,100) },{ name: "med",tooltip: "Okay.",range: _.range(101,149) },{ name: "high",tooltip: "Bad.",range: [150] }
];
// Loop every input elements
$element.each(function (index,element) {
var currentState;
var $handle;
// Instanciate on the element
$(element)
.rangeslider({
polyfill: false,onInit: function () {
$handle = $(".rangeslider__handle",this.$range);
updateHandle($handle[0],this.value);
updateState($handle[0],this.value);
}
})
.on("input",function () {
updateHandle($handle[0],this.value);
checkState($handle[0],this.value);
});
// Update the value inside the slider handle
function updateHandle(el,val) {
el.textContent = Math.round(0.25 * val) + "€";
}
// Check if the slider state has changed
function checkState(el,val) {
// if the value does not fall in the range of the current state,update that shit.
if (!_.contains(currentState.range,parseInt(val))) {
updateState(el,val);
}
}
// Change the state of the slider
function updateState(el,val) {
for (var j = 0; j < sliderStates.length; j++) {
if (_.contains(sliderStates[j].range,parseInt(val))) {
currentState = sliderStates[j];
// updateSlider();
}
}
// If the state is high,update the handle count to read 50+
if (currentState.name == "high") {
updateHandle($handle[0],"150");
}
// Update handle color
$handle
.removeClass(function (index,css) {
return (css.match(/(^|\s)js-\S+/g) || []).join(" ");
})
.addClass("js-" + currentState.name);
// Update tooltip
$(element).siblings(".rangeslider__tooltip").html(currentState.tooltip);
}
});
label {
display: block;
margin-bottom: 2.5em;
font-size: 13px;
font-weight: bold;
}
.rangeslider__tooltip {
display: block;
margin-top: 2.5em;
font-size: 12px;
color: #a59eb5;
max-width: max-content;
}
.rangeslider,input[type=range] {
max-width: 400px;
}
.rangeslider__handle {
border-radius: 22px;
line-height: 42px;
text-align: center;
font-weight: bold;
}
.rangeslider__handle:after {
background: 0;
}
.rangeslider,.rangeslider__fill {
display: block;
border-radius: 10px;
}
.rangeslider {
background: white;
background-image: linear-gradient(to right,#4bc67d 30%,#f1c40f 45%,#b94a48 99%);
position: relative;
}
.rangeslider--horizontal {
height: 7px;
width: 100%;
}
.rangeslider--vertical {
width: 20px;
min-height: 150px;
max-height: 100%;
}
.rangeslider--disabled {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
opacity: 0.4;
}
.rangeslider__fill {
position: absolute;
}
.rangeslider--horizontal .rangeslider__fill {
top: 0;
height: 100%;
}
.rangeslider--vertical .rangeslider__fill {
bottom: 0;
width: 100%;
}
.rangeslider__handle {
background: #e6e7ee;
border: 6px solid #4bc67d;
cursor: pointer;
display: inline-block;
width: 42px;
height: 42px;
position: absolute;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
font-size: small;
}
.rangeslider__handle.js-low {
border-color: #4bc67d;
}
.rangeslider__handle.js-med {
border-color: #f1c40f;
}
.rangeslider__handle.js-high {
border-color: #b94a48;
}
.rangeslider__handle:after {
content: "";
display: block;
width: 18px;
height: 18px;
margin: auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.rangeslider--horizontal .rangeslider__handle {
top: -20px;
touch-action: pan-y;
-ms-touch-action: pan-y;
}
.rangeslider--vertical .rangeslider__handle {
left: -10px;
touch-action: pan-x;
-ms-touch-action: pan-x;
}
input[type=range]:focus + .rangeslider .rangeslider__handle {
-moz-box-shadow: 0 0 8px rgba(255,255,0.9);
-webkit-box-shadow: 0 0 8px rgba(255,0.9);
box-shadow: 0 0 8px rgba(255,0.9);
}
<!DOCTYPE html>
<html lang="en" >
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
</head>
<body>
<div class="main">
<input
type="range"
name="participants"
min="80"
max="150"
value="99"
oninput="showVal(this.value)"
onchange="showVal(this.value)"
>
<span class="rangeslider__tooltip" id ="range-tooltip"></span>
<div class="main">
<input
type="range"
name="participants"
min="80"
max="150"
value="99"
oninput="showVal(this.value)"
onchange="showVal(this.value)"
>
<span class="rangeslider__tooltip" id ="range-tooltip"></span>
<script>
function showVal(newVal){
//console.log("updated");
}
</script>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://andreruffert.github.io/rangeslider.js/assets/rangeslider.js/dist/rangeslider.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore-min.js'></script>
</body>
</html>