Как верно сдвинуть ползунок rangeSlider?

Не могу понять, почему когда пробую сдвинуть ползунок, он сразу перемещается на длину container-marginLeft.

Пробовал с clientX, offsetX, но эффект тот же.

Еще пробовал вешать eventListener на сам элемент: this.createableElement.addEventListener('mousemove', this.moveClickHandler); но тогда он не двигается плавно, и вроде везде советуют обработчик вешать на document

Еще думал о том чтобы вычитать container-marginLeft, но по-моему это уже костыли.

Изначально руководствовался этой статьей, но так же не получается.

class Marker {
  constructor(selector) {
    this.$el = selector;
    this.createMarker();

    this.clickMarker();
  }

  clickMarker() {
    this.onMouseDown = this.onMouseDown.bind(this);
    this.createableElement.addEventListener('mousedown', this.onMouseDown);
  }

  onMouseDown(event) {
    event.preventDefault();
    this.moveClickHandler = this.moveClickHandler.bind(this);
    document.addEventListener('mousemove', this.moveClickHandler);
    this.onMouseUp = this.onMouseUp.bind(this);
    document.addEventListener('mouseup', this.onMouseUp);
  }

  moveClickHandler(event) {

    if (this.createableElement) {
      this.createableElement.ondragstart = () => false;
        this.createableElement.style.left = event.pageX - this.createableElement.offsetWidth / 2 +'px';
    }
  }

  onMouseUp() {
    document.removeEventListener('mousemove', this.moveClickHandler);
    document.removeEventListener('mouseup', this.onMouseUp);
  }

  createMarker() {
    this.createableElement = document.createElement('div');
    this.createableElement.classList.add('sliderM');
    this.$el.append(this.createableElement);
  }
}

const el1 = document.querySelector('#sliderID');
if (el1) {
  const newMarket = new Marker(el1);
}
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    .container{
      margin-top: 40px;
      margin-left: 50px;
      position: relative;
    }
    .bar{
      width: 400px;
      height: 30px;
      border: 2px solid blue;
    }
    .sliderM{
      width: 30px;
      height: 30px;
      background-color: blue;
      position: absolute;
      left: 0;
      top: 0;
    }
<div id="sliderID" class="container">
    <div class="bar"></div>
  </div>


Ответы (1 шт):

Автор решения: Miha

Вам нужно вычесть положение элемента по оси X

class Marker {
  constructor(selector) {
    this.$el = selector;
    this.createMarker();
    this.clickMarker();
  }

  clickMarker() {
    this.onMouseDown = this.onMouseDown.bind(this);
    this.createableElement.addEventListener('mousedown', this.onMouseDown);
  }

  onMouseDown(event) {
    event.preventDefault();
    this.moveClickHandler = this.moveClickHandler.bind(this);
    document.addEventListener('mousemove', this.moveClickHandler);
    this.onMouseUp = this.onMouseUp.bind(this);
    document.addEventListener('mouseup', this.onMouseUp);
  }

  moveClickHandler(event) {
    if (this.createableElement) {
      this.createableElement.ondragstart = () => false;
      // Вам нужно вычесть положение элемента по оси X
      // Добавил this.$el.offsetLeft
      this.createableElement.style.left = event.pageX - this.$el.offsetLeft - this.createableElement.offsetWidth / 2 + 'px';
    }
  }

  onMouseUp() {
    document.removeEventListener('mousemove', this.moveClickHandler);
    document.removeEventListener('mouseup', this.onMouseUp);
  }

  createMarker() {
    this.createableElement = document.createElement('div');
    this.createableElement.classList.add('sliderM');
    this.$el.append(this.createableElement);
  }
}

const el1 = document.querySelector('#sliderID');
if (el1) {
  const newMarket = new Marker(el1);
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  margin-top: 40px;
  margin-left: 50px;
  position: relative;
}

.bar {
  width: 400px;
  height: 30px;
  border: 2px solid blue;
}

.sliderM {
  width: 30px;
  height: 30px;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
}
<div id="sliderID" class="container">
  <div class="bar"></div>
</div>

→ Ссылка