The flickering of the days part in your code is likely caused by the frequent updates and recalculations you are making. I can think of a few reasons based on your code why this might be happening.
Your 'setTimeout' function does not guarantee exact timing which might lead to slight variations when your countdown is updated.
When you create a new Date object in your 'calculateTimeRemaining' there might be small inconsistencies.
When you use the 'Math.floor' function it can cause jumps when the remaining time is close to a day boundary/end.
See my code below as well as the working fiddle at
Eliminate date flickering[
^] where I used 'requestAnimationFrame' instead of your 'setTimeout' for smoother updates.
I also created a single 'Date' object for the current time and pass it to the 'calculateTimeRemaining' function.
The code will also calculate days with more precision to avoid rounding issues which leads to flickering.
function calculateTimeRemaining(endDate, now) {
const timeRemaining = endDate - now;
const days = timeRemaining / (1000 * 60 * 60 * 24);
const hours = (timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
const minutes = (timeRemaining % (1000 * 60 * 60)) / (1000 * 60);
const seconds = (timeRemaining % (1000 * 60)) / 1000;
return {
days: Math.floor(days),
hours: Math.floor(hours),
minutes: Math.floor(minutes),
seconds: Math.floor(seconds)
};
}
function startCountdown(element, endDate) {
let animationFrameId;
function updateCountdown() {
const now = new Date();
const { days, hours, minutes, seconds } = calculateTimeRemaining(endDate, now);
element.innerHTML = `
<div class="m-table__itm"><span>${days}</span><span>DAYS</span></div>
<div class="m-table__itm"><span>${hours}</span><span>HRS</span></div>
<div class="m-table__itm"><span>${minutes}</span><span>MIN</span></div>
<div class="m-table__itm"><span>${seconds}</span><span>SEC</span></div>
`;
if (endDate > now) {
animationFrameId = requestAnimationFrame(updateCountdown);
} else {
element.innerHTML = '<div class="m-table__itm"><span>-</span><span>DAYS</span></div><div class="m-table__itm"><span>-</span><span>HRS</span></div><div class="m-table__itm"><span>-</span><span>MIN</span></div><div class="m-table__itm"><span>-</span><span>SEC</span></div>';
}
}
updateCountdown();
return () => {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
}
};
}
startCountdown(document.getElementById(`countdown-${index}`), new Date(data.endDate));
const currentEndDate = new Date(currentDate.getFullYear(), currentMonth + 1, 0, 23, 59, 59);
const upcomingEndDate = new Date(currentDate.getFullYear(), currentMonth + 2, 0, 23, 59, 59);
if (currentDay <= 7) {
startCountdown(document.getElementById('countdown-0'), currentTimerEnd);
startCountdown(document.getElementById('countdown-1'), currentTimerEnd);
} else {
startCountdown(document.getElementById('countdown-0'), currentTimerEnd);
startCountdown(document.getElementById('countdown-1'), upcomingTimerEnd);
}