I am trying to create a blinking countdown timer, starting it at 5 seconds, and disappearing when it gets to 0.
CSS:
.blinky {
transition: 1s opacity;
-moz-transition: 1s opacity;
-webkit-transition: 1s opacity;
}
HTML:
<div id="countdown" class="blinky">
JS:
const cdStart = 5;
countdown.innerHTML = cdStart;
countdown.style.opacity = 0;
for (var i = cdStart - 1; i > 0; i--) {
setTimeout(
(x) => {
countdownTime.innerHTML = x;
countdown.classList.remove('blinky');
countdown.style.opacity = 1;
countdown.classList.add('blinky');
countdown.style.opacity = 0;
},
1000 * (cdStart - i),
i
);
}
What I want this to do is to show 5, fade out, 4, fade out, 3, fade out, 2, fade out, 1, fade out. When a new number is shown on the timer, I want it to show up instantly, and not fade back in. For that reason, I remove the "blinky" class before I set the opacity to 1, then add it back in before setting opacity to 0.
Unfortunately, this doesn't seem to work - 5 shows up and fades out, and then nothing else shows up. If I remove the manipulation of countdown's style (and just set the innerHTML in the for loop), I see that the timer displays properly (counts down from 3 to 1), so that's working.
I thought, maybe the browser is having trouble removing a class and then immediately adding it back in, so I separated those events by a bit:
CSS:
.blinky {
transition: .9s opacity;
-moz-transition: .9s opacity;
-webkit-transition: .9s opacity;
}
JS:
const cdStart = 5;
countdownTime.innerHTML = cdStart;
countdown.style.opacity = 0;
for (var i = cdStart - 1; i > 0; i--) {
setTimeout(
(x) => {
countdownTime.innerHTML = x;
countdown.classList.remove('blinky');
countdown.style.opacity = '';
},
1000 * (cdStart - i),
i
);
setTimeout(() => {
countdown.classList.add('blinky');
countdown.style.opacity = 0;
}, 1000 * (cdStart - i) + 100);
}
This one was closer - I saw 5, fade out, then nothing for a bit, and 1 came in and then faded out.
Is there a more reliable way to get the desired behavior here?