动态 Javascript 范围滑块

Dynamic Javascript Range Slider

所以我找到了这个范围滑块,我正试图让它动态化。目前,在 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, 0, 255, 0.9);
  -webkit-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9);
  box-shadow: 0 0 8px rgba(255, 0, 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 做了很多更改,但我的代码一直在更改同一范围滑块的颜色,因为我做错了。你能帮忙提供任何提示吗?非常感谢

由于 $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, 0, 255, 0.9);
  -webkit-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9);
  box-shadow: 0 0 8px rgba(255, 0, 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>