two-sides-slider
by Vladymyr Shevchuk
HTML
<div class="container">
<div id="start-value" class="value">0$</div>
<div class="slider">
<div id="field" class="field">
<div id="fill-left" class="fill left"> </div>
<div id="control-left" class="js-control-left control left"> </div>
<div id="fill-right" class="fill right"> </div>
<div id="control-right" class="js-control-right control right"> </div>
</div>
</div>
<div id="end-value" class="value">4000$</div>
</div>
CSS
.container {
outline: 1px dotted grey;
width: 300px;
height: 300px;
margin: auto;
display: flex;
align-items: center;
flex-direction: row;
}
.value {
width: 100px;
text-align: center;
}
.slider {
width: 100%;
height: 5px;
position: relative;
}
.field {
width: 100%;
height: 100%;
background: #109CF2;
position: absolute;
user-select: none;
}
.control {
border: 1px solid grey;
box-sizing: border-box;
width: 5px;
height: 16px;
background: white;
position: absolute;
margin: auto;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
user-select: none;
}
.control:active {
border-color: #8b8b8b;
background: #eaeaea;
}
.fill {
background: #eaeaea;
opacity: .5;
width: 5px;
height: 100%;
position: absolute;
}
.left {
left: 0px;
}
.right {
right: 0px;
}
JavaScript
const $field = document.getElementById('field');
const $fillLeft = document.getElementById('fill-left');
const $fillRight = document.getElementById('fill-right');
const $start = document.getElementById('start-value');
const $end = document.getElementById('end-value');
const $controlLeft = document.getElementById('control-left');
const $controlRight = document.getElementById('control-right');
const step = getSliderStep();
const { end: initEndValue } = getBoundariesValues();
$field.addEventListener('mousedown', event => {
const { target: control } = event;
if (control.classList.contains('js-control-left')) {
const boundary = getBoundary();
const { left } = $field.getBoundingClientRect();
const { offsetLeft } = control;
const shift = event.pageX - left - pageXOffset;
document.onmousemove = mouseMoveEvent => {
const move = offsetLeft + (mouseMoveEvent.pageX - left - shift);
if (move >= 0 && move <= boundary + offsetLeft) {
const { end } = getBoundariesValues();
const value = move * step;
const newBoundary = value > end ? end : value;
control.style.left = move + 'px';
$fillLeft.style.width = move + 'px';
changeBoundariesValues({start: newBoundary})
}
};
clearEventListeners();
}
if (control.classList.contains('js-control-right')) {
const boundary = getBoundary();
const { right, width } = $field.getBoundingClientRect();
const { offsetLeft } = control;
const shift = right - event.pageX + pageXOffset;
document.onmousemove = mouseMoveEvent => {
const rightPadding = width - offsetLeft - control.getBoundingClientRect().width;
const move = rightPadding + right - mouseMoveEvent.pageX - shift;
if (move >= 0 && move <= boundary + rightPadding) {
const { start } = getBoundariesValues();
const value = initEndValue - move * step;
const newBoundary = value < start ? start : value;
control.style.right =...