Click here to Skip to main content
15,886,788 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm Currently working on a project that requires multiple timers in the same page

They all print the same amount of remaining time despite the differences between the end time of each timer

Is there anyone who can modify this code or suggest a solution so it works perfectly

Thank you

here is the JS code:
JavaScript
const posts = [{
    title: 'Countdown 1',
    endTime: 'oct 12 2021 22:10:59 GMT+0200'
  },
  {
    title: 'Countdown 2',
    endTime: 'sep 30 2021 13:59:59 GMT+0200'
  },
  {
    title: 'Countdown 3',
    endTime: 'sep 25 2021 16:59:59 GMT+0200'
  }
];

// *********  the Timer function:  *********
function getRemainingTime(endTime) {
  const total = Date.parse(endTime) - Date.parse(new Date());
  const seconds = Math.floor((total / 1000) % 60);
  const minutes = Math.floor((total / 1000 / 60) % 60);
  const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
  const days = Math.floor(total / (1000 * 60 * 60 * 24));

  return {
    total,
    days,
    hours,
    minutes,
    seconds
  };
}

function initializeClock(endTime) {
  function updateClock() {
    const sections = document.querySelectorAll('section');
    const t = getRemainingTime(endTime);

    for (let i = 0; i < sections.length; i++) {
      const daysSpan = document.getElementsByClassName('di');
      const hoursSpan = document.getElementsByClassName('ho');
      const minutesSpan = document.getElementsByClassName('mi');
      const secondsSpan = document.getElementsByClassName('se');

      daysSpan[i].innerHTML = ('0' + t.days).slice(-2) + ' DAY(S)';
      hoursSpan[i].innerHTML = ('0' + t.hours).slice(-2) + ' HR(S)';
      minutesSpan[i].innerHTML = ('0' + t.minutes).slice(-2) + ' MIN(S)';
      secondsSpan[i].innerHTML = ('0' + t.seconds).slice(-2) + ' SEC(S)';
    }

    if (t.total <= 0) {
      clearInterval(timeinterval);
      document.getElementById('counter').innerHTML = "The countdown is over!"
    }
  }
  updateClock();
  const timeinterval = setInterval(updateClock, 1000);
}

// *********  the end of the Timer function:  *********    

// *********  the view function using javascript template literals:  ********* 
function postsItem(post) {

  return `<section>
            <h2 class="article-ttitle">${post.title}</h2>
            <article>
                <div id="counter" onload="${initializeClock(post.endTime)}">
                    
                    
                    
                    
                <div>
            </article>
        </section>`
}

document.getElementById('posts').innerHTML = `${posts.map(postsItem).join('')}`

and here is the html:
HTML
<pre><body>
  <div id="posts"></div>
</body>


What I have tried:

I have split up my logic into three functions so it is easier to manage and test: 1) input, 2) processing, 3) output. In part 2) processing, my output is t,  i return t and use it in my 3) output function
Posted
Updated 13-Sep-21 0:24am
v2

1 solution

Your updateClock method sets the same remaining time in every .section element in your document. You need to change it so that it only sets the time for the related element.

You'll also find that onload doesn't work for <div> elements. Your code currently calls the initializeClock method directly from the postsItem method, and inserts onload="undefined" into the HTML output. Instead, you should initialize the clocks after you have inserted them into the document.

For example:
JavaScript
function initializeClock(counter){
    function updateClock(){
        const endTime = counter.dataset.endTime;
        const t = getRemainingTime(endTime);
        if (t.total <= 0) {
            clearInterval(timeinterval);
            counter.innerHTML = "The countdown is over!"
            return;
        }
        
        const daysSpan = counter.getElementsByClassName('di');
        const hoursSpan = counter.getElementsByClassName('ho');
        const minutesSpan = counter.getElementsByClassName('mi');
        const secondsSpan = counter.getElementsByClassName('se');

        daysSpan[0].innerHTML = ('0' + t.days).slice(-2) + ' DAY(S)';
        hoursSpan[0].innerHTML = ('0' + t.hours).slice(-2) + ' HR(S)';
        minutesSpan[0].innerHTML = ('0' + t.minutes).slice(-2) + ' MIN(S)';
        secondsSpan[0].innerHTML = ('0' + t.seconds).slice(-2) + ' SEC(S)';
    }
    
    updateClock();
    const timeinterval = setInterval(updateClock, 1000);
}

function postsItem(post) {
    return `<section>
        <h2 class="article-ttitle">${post.title}</h2>
        <article>
            <div data-end-time="${post.endTime}">
                <span class="di"></span> Days
				<span class="ho"></span> Hours
				<span class="mi"></span> Minutes
				<span class="se"></span> Seconds
            <div>
        </article>
    </section>`;
}

const container = document.getElementById('posts');
container.innerHTML = `${posts.map(postsItem).join('')}`;
container.querySelectorAll("div[data-end-time]").forEach(initializeClock);
Demo[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900