DEV Community

Cover image for Improving my counter
Grant Smith
Grant Smith

Posted on

Improving my counter

I've created a count-up clock that I'd like some help refining if you wouldn't mind. Currently, I have two issues that are bugging (pun intended!) me.

  1. The counter doesn't count up the hours, when it reaches two hours, it goes back to 01:01:01
  2. The numbers jump around

Here is my code so far…

// Counter

if (!!document.getElementById("counter")) {
  var minutesLabel = document.getElementById("minutes");
  var secondsLabel = document.getElementById("seconds");
  var totalSeconds = Number(secondsLabel.textContent);
  var totalMinutes = Number(minutesLabel.textContent);

  setInterval(setTime, 1000);

  function setTime() {
   secondsLabel.innerHTML = pad(totalSeconds % 60);
   minutesLabel.innerHTML = pad(parseInt(totalMinutes + totalSeconds / 60));

  function pad(val) {
   var valString = val + "";
   if (valString.length < 2) {
    return "0" + valString;
   } else {
    return valString;

// End Counter
#counter {
  background-color: #ee1a25; // TODO: Change this to a pattern
  color: $white;
  text-align: center;

  .counter_wrapper {
    flex-direction: column;

    @include desktop {
      flex-direction: row;

  .counter_container {
    display: flex;
    align-items: center;
    flex-direction: row;
    justify-content: center;

    .counter_number {
      font-weight: regular;
      font-size: 60px;
      font-family: $family-primary;

      font-feature-settings: "tnum";
      font-variant-numeric: tabular-nums;
      @include widescreen {
        font-size: 133px;

    .divider {
      display: inline-block;
      margin: 0 16px;
      width: 8px;
      height: 30px;

      @include widescreen {
        margin: 0 34px;
        width: 16px;
        height: 60px;

I'd apprecitate any help and advice offered please

Oldest comments (5)

aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan • Edited
  1. Consider using String.prototype.padStart:

  2. You don't currently do anything with hours in the JavaScript, so that's why it's not changing. You're only setting the minutes and seconds. You'll need to get a reference to the hours label like you did with minutes and seconds and then set it to be parseInt(totalSeconds / 3600).

  3. Why do this? if (!!document.getElementById("counter"). Just do this: if (document.getElementById("counter")). Applying the negation operator twice is the same thing as not applying it at all.

Regarding this concern:

The numbers jump around

What do you mean? It may be helpful to include a link to a jsfiddle with all of your HTML, CSS, and JS so we can run it on our end.

One final thing to note: You don't need totalMinutes. Given a number of seconds, the number of minutes it represents is equal to parseInt(totalSeconds / 60) % 60. Since you're tallying the seconds, you don't need to also tally the minutes.

Improved code:

granttransition profile image
Grant Smith • Edited

This is fantastic, thank you. As for the numbers jumping around, I posted a gif at the top of the post. It is hopefully attached below, although this isn't that important.

One important thing though (customer request), I need the numbers to start from 01:34:06. Using your method, how would you set the starting numbers?

New Timer

aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan

how would you set the starting numbers

Just in the HTML, if it's a fixed start. Otherwise you can just use JS to allow users to enter a start time.

Thread Thread
granttransition profile image
Grant Smith • Edited

Yeah, that is exactly what I have done. Page loads with 01:32:20 and then changes the timer to 00:00:20.

<div class="column is-8 counter_container">
 <span id="hours" class="counter_number">01</span>
 <img class="divider" src="dist/svg/counter-divider.svg" alt="Counter divider" width="16" height="60">
 <span id="minutes" class="counter_number">32</span>
 <img class="divider" src="dist/svg/counter-divider.svg" alt="Counter divider" width="16" height="60">
 <span id="seconds" class="counter_number">20</span>

I'll keep working at it, the help is much appreciated, thank you

granttransition profile image
Grant Smith • Edited

Here is what I worked out; I never actually used the hours or minutes values in the HTML to start with. I was only using the seconds, calculating all the labels with that. The totalSeconds variable should account for the hours and minutes.

So here is the code I ended up with…

if (document.getElementById("counter")) {
  const hoursLabel = document.getElementById("hours");
  const minutesLabel = document.getElementById("minutes");
  const secondsLabel = document.getElementById("seconds");

    // add all the time values together to give a proper total start point
  let totalSeconds = 

  setInterval(setTime, 1000);

  function setTime() {

      // pull the number of hours out of the total for reference
     const numHours = parseInt(totalSeconds / 3600)

     //remove that number fromt he total because it messes up the /60 math if you have extra 3600's in there
     const secondsLeft = parseInt(totalSeconds - 3600 * numHours)

     // tweak these for new variables available
    secondsLabel.innerHTML = padWithZero(secondsLeft % 60);
    minutesLabel.innerHTML = padWithZero(parseInt(secondsLeft / 60));
    hoursLabel.innerHTML = padWithZero(numHours);

  function padWithZero(num) {
    return Number(num)
      .padStart(2, "0");