Ползунок динамического диапазона Javascript

Итак, я нашел этот ползунок диапазона и пытаюсь сделать его динамичным. В настоящее время в JS есть некоторый жестко закодированный контент, непосредственно относящийся к определенным элементам HTML, и я хотел бы, чтобы 10 из этих ползунков на моем HTML-сайте работали независимо. Я использую следующий код: 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, но мой код продолжает менять цвет одного и того же ползунка диапазона, потому что я делаю это неправильно. Не могли бы вы помочь с какими-либо намеками? Спасибо большое


person Genesis1337    schedule 27.01.2021    source источник


Ответы (1)


Поскольку $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>

person Louys Patrice Bessette    schedule 27.01.2021
comment
Большое спасибо за объяснение. Мне интересно, могу ли я также создать всплывающую подсказку, которая отображает сообщение поверх JS... - person Genesis1337; 27.01.2021
comment
Конечно... Я отредактировал. - person Louys Patrice Bessette; 27.01.2021
comment
спасибо. - person Genesis1337; 28.01.2021
comment
Можете ли вы отметить ответ как принятый с помощью зеленой галочки? - person Louys Patrice Bessette; 28.01.2021