Home > Mobile >  trying to make a count up timer and it the word "days" isnt showing up
trying to make a count up timer and it the word "days" isnt showing up

Time:12-09

I'm trying to make a count up timer but the word days doesn't seem to want to show up on the screen

HTML

<div  id="countup1">
<div ><span >00</span><span >YRS</span></div> |
<div ><span >00</span><span >DAYS</span></div> |
<div ><span >00</span><span >HRS</span></div> |
<div ><span >00</span><span >MINS</span></div> |
<div ><span >00</span><span >SECS</span></div>
                    </div>

JS

window.onload = function () {
    countUpFromTime("Dec 25, 2021 13:20:00", 'countup1');
};
function countUpFromTime(countFrom, id) {
    countFrom = new Date(countFrom).getTime();
    var now = new Date(),
        countFrom = new Date(countFrom),
        timeDifference = (now - countFrom);

    var secondsInADay = 60 * 60 * 1000 * 24,
        secondsInAHour = 60 * 60 * 1000;

    days = Math.floor(timeDifference / (secondsInADay) * 1);
    years = Math.floor(days / 365);
    if (years > 1) { days = days - (years * 365) }
    hours = Math.floor((timeDifference % (secondsInADay)) / (secondsInAHour) * 1);
    mins = Math.floor(((timeDifference % (secondsInADay)) % (secondsInAHour)) / (60 * 1000) * 1);
    secs = Math.floor((((timeDifference % (secondsInADay)) % (secondsInAHour)) % (60 * 1000)) / 1000 * 1);

    var idEl = document.getElementById(id);
    idEl.getElementsByClassName('years')[0].innerHTML = years;
    idEl.getElementsByClassName('days')[0].innerHTML = days;
    idEl.getElementsByClassName('hours')[0].innerHTML = hours;
    idEl.getElementsByClassName('minutes')[0].innerHTML = mins;
    idEl.getElementsByClassName('seconds')[0].innerHTML = secs;

    clearTimeout(countUpFromTime.interval);
    countUpFromTime.interval = setTimeout(function () { countUpFromTime(countFrom, id); }, 1000);
}

I've tried doing

<div ><span >00</span><span id="countupDays" >DAYS</span></div>

JS

document.getElementById('countupDays').innerHTML = "DAYS";

to add the word days but that did not work because the timer would stop counting

CodePudding user response:

It's because you had a side effect having the outer element with class days

window.onload = function() {
  countUpFromTime("Dec 25, 2021 13:20:00", 'countup1');
};

function countUpFromTime(countFrom, id) {
  countFrom = new Date(countFrom).getTime();
  var now = new Date(),
    countFrom = new Date(countFrom),
    timeDifference = (now - countFrom);

  var secondsInADay = 60 * 60 * 1000 * 24,
    secondsInAHour = 60 * 60 * 1000;

  days = Math.floor(timeDifference / (secondsInADay) * 1);
  years = Math.floor(days / 365);
  if (years > 1) {
    days = days - (years * 365)
  }
  hours = Math.floor((timeDifference % (secondsInADay)) / (secondsInAHour) * 1);
  mins = Math.floor(((timeDifference % (secondsInADay)) % (secondsInAHour)) / (60 * 1000) * 1);
  secs = Math.floor((((timeDifference % (secondsInADay)) % (secondsInAHour)) % (60 * 1000)) / 1000 * 1);

  var idEl = document.getElementById(id);
  idEl.getElementsByClassName('years')[0].innerHTML = years;
  idEl.getElementsByClassName('days')[0].innerHTML = days;
  idEl.getElementsByClassName('hours')[0].innerHTML = hours;
  idEl.getElementsByClassName('minutes')[0].innerHTML = mins;
  idEl.getElementsByClassName('seconds')[0].innerHTML = secs;

  clearTimeout(countUpFromTime.interval);
  countUpFromTime.interval = setTimeout(function() {
    countUpFromTime(countFrom, id);
  }, 1000);
}
<div  id="countup1">
  <div ><span >00</span><span >YRS</span></div> |
  <div ><span >00</span><span >DAYS</span></div> |
  <div ><span >00</span><span >HRS</span></div> |
  <div ><span >00</span><span >MINS</span></div> |
  <div ><span >00</span><span >SECS</span></div>
</div>

CodePudding user response:

The issue is really how you're selecting your elements. Because there are multiple elements with the class days, using getElementsByClass is returning multiple elements so idEl.getElementsByClassName('days')[0] is selecting the div, not the span. You could consider removing un-needed classes from your HTML but it's actually perfectly possible to select the correct element with the right selector.

Here is a version that does that (also uses setInterval instead of setTimeout to avoid having to manually restart the timeout).

var timeoutId

window.onload = function () {
  timeoutId = countUpFromTime("Dec 25, 2021 13:20:00", 'countup1')
};

function countUpFromTime(from, id) {
  const secondsInADay = 60 * 60 * 1000 * 24,
        secondsInAHour = 60 * 60 * 1000;

  const countFrom = new Date(from).getTime();

  // The keys of counter are the class names of the spans that should contain the result of the value method
  const counter = {
    days: (timeDifference) => ( Math.floor(timeDifference / (secondsInADay) * 1) % 365 ),
    years: (timeDifference) => Math.floor(Math.floor(timeDifference / (secondsInADay) * 1) / 365),
    hours: (timeDifference) => Math.floor((timeDifference % (secondsInADay)) / (secondsInAHour) * 1),
    minutes: (timeDifference) => Math.floor(((timeDifference % (secondsInADay)) % (secondsInAHour)) / (60 * 1000) * 1),
    seconds: (timeDifference) => Math.floor((((timeDifference % (secondsInADay)) % (secondsInAHour)) % (60 * 1000)) / 1000 * 1)
  }

  return setInterval( () => {
    let now = new Date(),
        timeDifference = (now - new Date(countFrom));

    for (const [key, value] of Object.entries(counter)) {
      document.querySelector(`#${id} span.${key}`).innerHTML = value(timeDifference)
    }
  }, 1)
}
<body>
<div  id="countup1">
<div ><span >00</span><span >YRS</span></div> |
<div ><span >00</span><span >DAYS</span></div> |
<div ><span >00</span><span >HRS</span></div> |
<div ><span >00</span><span >MINS</span></div> |
<div ><span >00</span><span >SECS</span></div>
</div>

You could replace the counter Object with a Map and use the result of the selector as the key, but that seems excessively complicated for minor performance gains:

    const counter = new Map()
    counter.set(document.querySelector(`#${id} span.days`), (timeDifference) => ( Math.floor(timeDifference / (secondsInADay) * 1) % 365 ))
    counter.set(document.querySelector(`#${id} span.years`), etc etc
    ...

    for (const [key, value] of counter.entries()) {
      key.innerHTML = value(timeDifference)
    }  
  • Related