Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Расчет диапазона значений между двумя ползунками

#javascript


Есть имитация input type="range" на javascript.



function Range(container) {
  this.container = container;
  if (!this.container) return;
  this.inputMin = container.querySelector('[data-type=input-min]');
  this.inputMax = container.querySelector('[data-type=input-max]');
  this.minValue = parseFloat(container.querySelector('[data-type=min-val]').textContent.replace(/\s/g,
''));
  this.maxValue = parseFloat(container.querySelector('[data-type=max-val]').textContent.replace(/\s/g,
''));
  this.inner = container.querySelector('[data-type=range-inner-element]');
  this.valuesElem = container.querySelector('[data-type=range-element]');
  this.minBtn = container.querySelector('[data-type=min-btn]');
  this.maxBtn = container.querySelector('[data-type=max-btn]');

  //console.log(this);
  this.init();
}
Range.prototype.drag = function(event) {
  function move(event) {
    var left = event.pageX - elemX - boxX;
    if (elem == this.minBtn) {
      this.inner.style.left = elem.offsetLeft + elem.offsetWidth / 2 + 'px';
      if (left < 0) {
        left = 0;
      }
      if (left > this.maxBtn.offsetLeft - elem.offsetWidth) {
        left = this.maxBtn.offsetLeft - elem.offsetWidth;
      }
    } else if (elem == this.maxBtn) {
      this.inner.style.right = elem.offsetLeft - elem.offsetWidth / 2 + 'px';
      if (left < this.minBtn.offsetLeft + elem.offsetWidth) {
        left = this.minBtn.offsetLeft + elem.offsetWidth;
      }
      if (left > this.valuesElem.offsetWidth - elem.offsetWidth) {
        left = this.valuesElem.offsetWidth - elem.offsetWidth;
      }
    }
    elem.style.left = left + 'px';
    this.inner.style.width = this.maxBtn.offsetLeft - this.minBtn.offsetLeft + 'px';
  }

  function removeMove() {
    document.removeEventListener('mousemove', move);
    document.removeEventListener('mouseup', removeMove);
  }
  if (event.target == this.minBtn || event.target == this.maxBtn) {
    var elem = event.target;
    var elemX = event.pageX - elem.getBoundingClientRect().left;
    var boxX = this.valuesElem.getBoundingClientRect().left;
    var coord = event.target.offsetLeft;
    move = move.bind(this);
    document.addEventListener('mousemove', move);
    document.addEventListener('mouseup', removeMove);
    event.target.ondragstart = function() {
      return false;
    };
  }
}
Range.prototype.setValue = function() {
  this.inputMin.value = this.minValue;
  this.inputMax.value = this.maxValue;
}
Range.prototype.init = function() {
  this.inner.style.left = this.minBtn.offsetLeft + this.minBtn.offsetWidth / 2 + 'px';
  this.inner.style.right = this.maxBtn.offsetLeft - this.maxBtn.offsetWidth / 2 + 'px';
  this.setValue();
  this.valuesElem.addEventListener('mousedown', this.drag.bind(this));
}
var range = new Range(document.querySelector('[data-type=range]'));
.filters_section_list {
  width: 300px;
  list-style: none
}

.filters_section_item .range {
  height: 6px;
  background-color: #AEAEAE;
  border-radius: 4px;
  position: relative;
}

.filters_section_item .range_inner {
  height: inherit;
  background-color: #FD2016;
}

.filters_section_item .range_btn {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.6);
  position: absolute;
  top: -7px;
  background-color: #fff;
  cursor: pointer;
}

.filters_section_item .range_inner {
  position: absolute;
  width: 100%;
}

.filters_section_item .range_btn[data-type=min-btn] {
  left: 0;
}

.filters_section_item .range_btn[data-type=max-btn] {
  left: 100%;
}

.filters_section_item .values {
  overflow: hidden;
  margin-top: 40px;
}

.filters_section_item .values .min-value {
  float: left;
  width: 35%;
  text-align: left;
  padding-bottom: 14px;
  padding-left: 10px;
  padding-right: 10px;
  border-bottom: 1px solid #ACACAC;
}

.filters_section_item .values .max-value {
  float: right;
  width: 35%;
  text-align: right;
  padding-bottom: 14px;
  padding-left: 10px;
  padding-right: 10px;
  border-bottom: 1px solid #ACACAC;
}
  • 0 1000000
Подскажите алгоритм как рассчитывать теперь диапазон значений между ползунками при их перемещении?


Ответы

Ответ 1



function Range(container) { this.container = container; if (!this.container) return; this.inputMin = container.querySelector('[data-type=input-min]'); this.inputMax = container.querySelector('[data-type=input-max]'); this.minValue = parseFloat(container.querySelector('[data-type=min-val]').textContent.replace(/\s/g, '')); this.maxValue = parseFloat(container.querySelector('[data-type=max-val]').textContent.replace(/\s/g, '')); this.inner = container.querySelector('[data-type=range-inner-element]'); this.valuesElem = container.querySelector('[data-type=range-element]'); this.minBtn = container.querySelector('[data-type=min-btn]'); this.maxBtn = container.querySelector('[data-type=max-btn]'); //console.log(this); this.init(); } Range.prototype.drag = function(event) { function move(event) { var left = event.pageX - elemX - boxX; var target; if (elem == this.minBtn) { this.inner.style.left = elem.offsetLeft + elem.offsetWidth / 2 + 'px'; if (left < 0) { left = 0; } if (left > this.maxBtn.offsetLeft - elem.offsetWidth) { left = this.maxBtn.offsetLeft - elem.offsetWidth; } target = this.container.querySelector('[data-type=min-val]'); } else if (elem == this.maxBtn) { this.inner.style.right = elem.offsetLeft - elem.offsetWidth / 2 + 'px'; if (left < this.minBtn.offsetLeft + elem.offsetWidth) { left = this.minBtn.offsetLeft + elem.offsetWidth; } if (left > this.valuesElem.offsetWidth - elem.offsetWidth) { left = this.valuesElem.offsetWidth - elem.offsetWidth; } target = this.container.querySelector('[data-type=max-val]'); } elem.style.left = left + 'px'; this.inner.style.width = this.maxBtn.offsetLeft - this.minBtn.offsetLeft + 'px'; target.innerText = this.minValue + (this.maxValue - this.minValue)*(left/this.valuesElem.offsetWidth); } function removeMove() { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', removeMove); } if (event.target == this.minBtn || event.target == this.maxBtn) { var elem = event.target; var elemX = event.pageX - elem.getBoundingClientRect().left; var boxX = this.valuesElem.getBoundingClientRect().left; var coord = event.target.offsetLeft; move = move.bind(this); document.addEventListener('mousemove', move); document.addEventListener('mouseup', removeMove); event.target.ondragstart = function() { return false; }; } } Range.prototype.setValue = function() { this.inputMin.value = this.minValue; this.inputMax.value = this.maxValue; } Range.prototype.init = function() { this.inner.style.left = this.minBtn.offsetLeft + this.minBtn.offsetWidth / 2 + 'px'; this.inner.style.right = this.maxBtn.offsetLeft - this.maxBtn.offsetWidth / 2 + 'px'; this.setValue(); this.valuesElem.addEventListener('mousedown', this.drag.bind(this)); } var range = new Range(document.querySelector('[data-type=range]')); .filters_section_list { width: 300px; list-style: none } .filters_section_item .range { height: 6px; background-color: #AEAEAE; border-radius: 4px; position: relative; } .filters_section_item .range_inner { height: inherit; background-color: #FD2016; } .filters_section_item .range_btn { width: 18px; height: 18px; border-radius: 50%; box-shadow: 0 0 3px rgba(0, 0, 0, 0.6); position: absolute; top: -7px; background-color: #fff; cursor: pointer; } .filters_section_item .range_inner { position: absolute; width: 100%; } .filters_section_item .range_btn[data-type=min-btn] { left: 0; } .filters_section_item .range_btn[data-type=max-btn] { left: 100%; } .filters_section_item .values { overflow: hidden; margin-top: 40px; } .filters_section_item .values .min-value { float: left; width: 35%; text-align: left; padding-bottom: 14px; padding-left: 10px; padding-right: 10px; border-bottom: 1px solid #ACACAC; } .filters_section_item .values .max-value { float: right; width: 35%; text-align: right; padding-bottom: 14px; padding-left: 10px; padding-right: 10px; border-bottom: 1px solid #ACACAC; }
  • 0 1000000
UP: Для тех, кто слишком давно учился в школе: left // расстояние от минимального значения до текущего значения в пикселях. // Всё, что нам нужно сделать - это перевести его из пикселей в шкалу, заданную минимальным и максимальным значением - this.valuesElem.offsetWidth //размер шкалы в пикселях scale = maxValue - minValue; // размер шкалы в еденицах шкалы percent = left/offsetWidth // отношение отрезка значения к размеру шкалы (безразмерное, тк пиксели делим на пиксели - получаем разы) value = minValue + scale*percent; // осталось домножить эти разы на размер шкалы в нужных единицах и прибавить к значению, с которого шкала начинается. // Выкидываем лишние промежуточные переменные, получается - value = this.minValue + (this.maxValue - this.minValue)*(left/this.valuesElem.offsetWidth);

Комментариев нет:

Отправить комментарий