I'm making a custom slider and I'm having the following problem, when my mouse quickly moves horizontally outside the slider's range, beyond the slider's width, the slider's value doesn't ideally go to min or max, instead Is there a pause, is there any way to make it slide smoothly?
const elWrap = document.getElementById('wrap');
const elProgress = document.getElementById('progress');
function onm ouseMove(event) {
const {clientX} = event
const {left, right} = elWrap.getBoundingClientRect()
// is the mouse inside the wrap?
if (clientX < left || clientX > right) return
// set progress width
elProgress.style.width = `${(clientX - left) / elWrap.offsetWidth * 100}%`
}
// slider mousedown events
elWrap.addEventListener('mousedown', function () {
window.addEventListener('mousemove', onm ouseMove);
window.addEventListener('mouseup', function () {
window.removeEventListener('mousemove', onm ouseMove);
}, {once: true});
});
.x {
padding: 128px;
}
#wrap {
border-radius: 999px;
width: 320px;
height: 12px;
background-color: #ccc;
cursor: pointer;
}
#progress {
height: 12px;
width: 50%;
border-radius: 999px;
background-color: blue;
}
<div >
<div id="wrap">
<div id="progress"></div>
</div>
</div>
CodePudding user response:
Problem
You are moving your mouse out of the range that the mousemove event is registered outside of the range, but you have this line which just ignores such events:
if (clientX < left || clientX > right) return
Solution
Handle out of range events
if (clientX < left) {
elProgress.style.width = `${0}%`;
} else if (clientX > right) {
elProgress.style.width = `${100}%`;
} else {
elProgress.style.width = `${((clientX - left) / elWrap.offsetWidth) * 100}%`;
}
const elWrap = document.getElementById('wrap');
const elProgress = document.getElementById('progress');
function onm ouseMove(event) {
const {
clientX
} = event
const {
left,
right
} = elWrap.getBoundingClientRect()
if (clientX < left) {
elProgress.style.width = `${0}%`
} else if (clientX > right) {
elProgress.style.width = `${100}%`
} else {
elProgress.style.width = `${(clientX - left) / elWrap.offsetWidth * 100}%`
}
}
// slider mousedown events
elWrap.addEventListener('mousedown', function() {
window.addEventListener('mousemove', onm ouseMove);
window.addEventListener('mouseup', function() {
window.removeEventListener('mousemove', onm ouseMove);
}, {
once: true
});
});
.x {
padding: 128px;
}
#wrap {
border-radius: 999px;
width: 320px;
height: 12px;
background-color: #ccc;
cursor: pointer;
}
#progress {
height: 12px;
width: 50%;
border-radius: 999px;
background-color: blue;
}
<div >
<div id="wrap">
<div id="progress"></div>
</div>
</div>