Вы можете получить позицию щелчка в процентах ширины элементов вдоль оси x, например:
document.getElementById('progress').addEventListener('click', function(e) {
var bcr = this.getBoundingClientRect();
console.log('You clicked to ', (e.clientX - bcr.left) / bcr.width);
});
Проблема при вычислениях с e.clientX
и element.offsetLeft
заключается в том, что они представляют две разные вещи.
element.offsetLeft
- это целое число, представляющее смещение влево в пикселях от ближайшего относительно расположенного родительского элемента.
источник
e.clientX
предоставляет горизонтальную координату в клиентской области приложения, в которой произошло событие (в отличие от координаты на странице). источник
Это вызывает проблемы, если пользователь, например, выполняет вертикальную прокрутку. Вы можете использовать e.pageX
, тогда оба они основаны на DOM, но вам все равно нужно суммировать все offsetLeft
s от родительских элементов element
, чтобы обе позиции относились к левому краю всего документа.
Пример индикатора выполнения:
function mouseSliderPosition(element, e) {
var bcr = element.getBoundingClientRect();
return {
x: Math.min(Math.max(0, (e.clientX - bcr.left) / bcr.width), 1),
y: Math.min(Math.max(0, (e.clientY - bcr.top) / bcr.height), 1)
}
};
function activateSlider(e) {
if (e.touches && e.touches.length > 1) {
return;
}
e.preventDefault();
window.activeSlider = this;
handleSliderMove(e);
}
function handleSliderMove(e) {
if (e.touches && e.touches.length > 1) {
return;
}
if (window.activeSlider) {
var progressBar = window.activeSlider.getElementsByClassName('progress-bar')[0];
var progressFill = window.activeSlider.getElementsByClassName('progress-fill')[0];
var value = mouseSliderPosition(progressBar, e.touches && e.touches[0] || e).x;
progressFill.style.transform = 'scaleX(' + value + ')';
}
}
function deactivateSlider(e) {
if (e.touches && e.touches.length > 0) {
return;
}
this.activeSlider = null;
}
document.querySelector('.progress-slider').addEventListener('mousedown', activateSlider)
document.querySelector('.progress-slider').addEventListener('touchstart', activateSlider)
window.addEventListener('mousemove', handleSliderMove);
window.addEventListener('mouseup', deactivateSlider);
window.addEventListener('touchmove', handleSliderMove);
window.addEventListener('touchend', deactivateSlider);
window.activeSlider = null;
.progress-slider {
padding: 10px;
cursor: pointer;
}
.progress-bar {
height: 2px;
background: rgba(100,100,100,0.5);
}
.progress-slider:hover .progress-bar {
height: 3px;
}
.progress-fill {
height: 100%;
background: rgba(255, 0, 0, 0.7);
transform-origin: 0 50%;
transform: scaleX(0);
}
<div class="progress-slider">
<div class="progress-bar"><div class="progress-fill"></div></div>
</div>