Reputation: 4984
I have a demo here
I have a bar made up of blocks with a marker on top and an input field
Inputting numbers in the input field will slide the marker to that percent
The blocks should change color when the marker is over that block.
This works but the blocks only change color after the marker has moved to another block or the enter is clicked again.
Why doesn't the block change color when the marker moves to that block.
const marker = document.querySelector('.bar-marker');
const bars = document.querySelectorAll('.bar-item');
const input = document.querySelector('.value');
(function() {
input.addEventListener("keyup", (event) => {
event.preventDefault();
if (event.keyCode === 13) {
const inputVal = document.querySelector('.value').value;
moveBar(inputVal)
}
})
function moveBar(val){
marker.style.left = val + '%';
for(let i=0; i<=bars.length; i++){
bars[i].classList.remove('selected')
if(marker.offsetLeft >
bars[i].offsetLeft && marker.offsetLeft <
bars[i].offsetWidth+bars[i].offsetLeft){
bars[i].classList.add('selected')
}
}
}
})();
Upvotes: 1
Views: 197
Reputation: 507
I chose to separate the classList.remove and the classList.add, so as soon as the new value is entered, the color bars reset immediately and then change once the marker stops:
const marker = document.querySelector('.bar-marker');
const bars = document.querySelectorAll('.bar-item');
const input = document.querySelector('.value');
(function() {
input.addEventListener("keyup", (event) => {
event.preventDefault();
if (event.keyCode === 13) {
const inputVal = document.querySelector('.value').value;
moveBar(inputVal)
}
})
function moveBar(val){
marker.style.left = val + '%';
for(let i=0; i<bars.length; i++){
bars[i].classList.remove('selected')
}
setTimeout(function() {
for (let i=0; i < bars.length; i++) {
if(marker.offsetLeft >
bars[i].offsetLeft && marker.offsetLeft <
bars[i].offsetWidth+bars[i].offsetLeft){
bars[i].classList.add('selected')
}
}
}, 2000)
}
})();
Upvotes: 2
Reputation: 980
its because you have a 2s animation
transition for the slider which mean marker.offsetLeft
will have the value of starting point of the slider because of the 2s delay
for reaching its destination. Solution would be to wait for 2s
so that the animation can end and then run the script.
Using setTimeout
of 2.1s could work.
function moveBar(val){
marker.style.left = val + '%';
setTimeout(function(){
for(let i=0; i<=bars.length; i++){
bars[i].classList.remove('selected')
if(marker.offsetLeft >
bars[i].offsetLeft && marker.offsetLeft <
bars[i].offsetWidth+bars[i].offsetLeft){
bars[i].classList.add('selected')
}
}
}, 2100);
}
Upvotes: 4