Выбор диапазона значений на основе плагина noUiSlider

В статье рассмотрим один из вариантов, как сделать выбор диапазона значений, который обычно используется в фильтрах интернет-магазинов

В данном примере будем использовать плагин noUiSlider и сделаем связывание значений с input-полями



Структура HTML

Необходимые файлы плагина noUiSlider можно взять здесь https://cdnjs.com/libraries/noUiSlider

Нас интересуют nouislider.min.css и nouislider.min.js

Подключаем плагин и пишем структуру

Элементам слайдера (<div id="range"></div>, <input id="min" type="text"/>, <input id="max" type="text"/>) задаем идентификаторы для использования в Javascript коде

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Range Slider</title>
    <link rel="stylesheet" href="css/reset.min.css"/>
    <link rel="preconnect" href="https://fonts.googleapis.com"/>
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="crossorigin"/>
    <link href="https://fonts.googleapis.com/css2?family=Rubik&amp;display=swap" rel="stylesheet"/>
    <link rel="stylesheet" href="css/nouislider.min.css"/>
    <link rel="stylesheet" href="css/main.css"/>
  </head>
  <body>
    <section class="range">
      <div class="container">
        <div class="range__title">
          <h2>Range Slider</h2>
        </div>
        <div class="range__slider">
          <div id="range"></div> <!-- элемент слайдера диапазона -->
        </div>
        <div class="range__values">
          <input id="min" type="text"/> <!-- меньшее установленное значение -->
          <input id="max" type="text"/> <!-- большее установленное значение -->
        </div>
      </div>
    </section>
    <script src="js/nouislider.min.js"></script>
    <script src="js/main.js"></script>
  </body>
</html>


CSS стили

Стилизуем слайдер

.noUi-target - основная полоса слайдера
.noUi-connect - активный диапазон между выбранными значениями
.noUi-handle - элементы управления

body {
  font-family: 'Rubik', sans-serif;
  color: #fff;
}
.container {
  max-width: 720px;
  margin: 0 auto;
  padding: 0 16px;
}
.range {
  padding: 48px 0;
  background: #222;
}
.range__title {
  text-align: center;
  margin-bottom: 32px;
}
.range__slider {
  margin-bottom: 24px;
}
.range__values {
  display: flex;
  gap: 24px;
}
.range__values input {
  width: 100%;
  border: none;
  height: 48px;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.1);
  text-align: center;
  font-size: 18px;
  color: #fff;
}
.range__values input:nth-child(1) {
  background: #6a00ff;
  box-shadow: 0 0 16px #6a00ff;
}
.range__values input:nth-child(2) {
  background: #ff0052;
  box-shadow: 0 0 16px #ff0052;
}
.range__values input:focus {
  outline: none;
}
.noUi-connect {
  background: linear-gradient(90deg, #6a00ff 0%, #ff0052 100%);
}
.noUi-target {
  box-shadow: 0 0 16px #6a00ff;
  border: none;
  background: #111;
}
.noUi-handle {
  box-shadow: 0 4px 16px rgba(0,0,0,0.24);
  border: none;
  border-radius: 50%;
  background: #111;
}
.noUi-handle:before,
.noUi-handle:after {
  display: none;
}
.noUi-handle-lower {
  background: #6a00ff;
  box-shadow: 0 0 16px #6a00ff;
}
.noUi-handle-upper {
  background: #ff0052;
  box-shadow: 0 0 16px #ff0052;
}
.noUi-horizontal {
  height: 13px;
}
.noUi-horizontal .noUi-handle {
  width: 24px;
  height: 24px;
  right: -12px;
}


Пишем Javascript код

Код с комментариями

const rangeSliderInit = () => { // создаем функцию инициализации слайдера
  const range = document.getElementById('range'); // Ищем слайдер
  const inputMin = document.getElementById('min'); // Ищем input с меньшим значнием
  const inputMax = document.getElementById('max'); // Ищем input с большим значнием

  if (!range || !inputMin || !inputMax) return // если этих элементов нет, прекращаем выполнение функции, чтобы не было ошибок

  const inputs = [inputMin, inputMax]; // создаем массив из меньшего и большего значения
  
  noUiSlider.create(range, { // инициализируем слайдер
      start: [20, 80], // устанавливаем начальные значения
      connect: true, // указываем что нужно показывать выбранный диапазон
      range: { // устанавливаем минимальное и максимальное значения
        'min': 0,
        'max': 100
      },
      step: 1, // шаг изменения значений
    }
  )
  
  range.noUiSlider.on('update', function (values, handle) { // при изменений положения элементов управления слайдера изменяем соответствующие значения
    inputs[handle].value = parseInt(values[handle]);
  });
  
  inputMin.addEventListener('change', function () { // при изменении меньшего значения в input - меняем положение соответствующего элемента управления
    range.noUiSlider.set([this.value, null]);
  });
  
  inputMax.addEventListener('change', function () { // при изменении большего значения в input - меняем положение соответствующего элемента управления
    range.noUiSlider.set([null, this.value]);
  });
  
}

const init = () => {
  rangeSliderInit() // запускаем функцию инициализации слайдера
}

window.addEventListener('DOMContentLoaded', init) // запускаем функцию init, когда документ будет загружен и готов к взаимодействию


Результат