0

I'm trying to use this countdown in a wordpress page:

https://codepen.io/varzin/pen/rFfhH

It works on, but I need to use it several times in the same page.

document.getElementById("timer")

I tried to change to document.getElementsbyClassName("timer") but it didn't work.

Am I missing something?

function updateTimer() {
  future = Date.parse("June 11, 2021 11:30:00");
  now = new Date();
  diff = future - now;

  days = Math.floor(diff / (1000 * 60 * 60 * 24));
  hours = Math.floor(diff / (1000 * 60 * 60));
  mins = Math.floor(diff / (1000 * 60));
  secs = Math.floor(diff / 1000);

  d = days;
  h = hours - days * 24;
  m = mins - hours * 60;
  s = secs - mins * 60;

  document.getElementById("timer")
    .innerHTML =
    '<div>' + d + '<span>days</span></div>' +
    '<div>' + h + '<span>hours</span></div>' +
    '<div>' + m + '<span>minutes</span></div>' +
    '<div>' + s + '<span>seconds</span></div>';
}
setInterval('updateTimer()', 1000);
body {
  text-align: center;
  padding: 70px 50px;
  background: #0D1A29;
  font-family: "Helvetica Neue", "Open Sans", helvetica, arial, sans-serif;
}

#timer {
  font-size: 3em;
  font-weight: 100;
  color: white;
  text-shadow: 0 0 20px #48C8FF;
  div {
    display: inline-block;
    min-width: 90px;
    span {
      color: #B1CDF1;
      display: block;
      font-size: .35em;
      font-weight: 400;
    }
  }
}
<div id="timer"></div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • You can not just switch from `getElementById` to `getElementsbyClassName`, and expect things to work. The first returns one single element, the second returns an HTMLCollection – you will have to _loop over_ the elements in that collection, and then do stuff with them individually. (And if you don’t want the _same_ counter value for all those elements, then you will have to make even further modifications to the whole thing.) – CBroe Aug 19 '20 at 12:45
  • If you needed two different timers, you should look at my answer – mplungjan Aug 19 '20 at 13:08

4 Answers4

1

You need use Array of elements, and foreach element change text. But better create Class or function for specify future

Your demo with array of timers: https://codepen.io/Nekiy2/pen/NWNRgPz

function updateTimer() {
  future = Date.parse("June 11, 2020 11:30:00");
  now = new Date();
  diff = future - now;

  days = Math.floor(diff / (1000 * 60 * 60 * 24));
  hours = Math.floor(diff / (1000 * 60 * 60));
  mins = Math.floor(diff / (1000 * 60));
  secs = Math.floor(diff / 1000);

  d = days;
  h = hours - days * 24;
  m = mins - hours * 60;
  s = secs - mins * 60;

  let timers = document.querySelectorAll('.timer')
  timers.forEach((e) => { // array of timers

    e.innerHTML =
      '<div>' + d + '<span>days</span></div>' +
      '<div>' + h + '<span>hours</span></div>' +
      '<div>' + m + '<span>minutes</span></div>' +
      '<div>' + s + '<span>seconds</span></div>';
  })
}
setInterval('updateTimer()', 1000);
body {
  text-align: center;
  padding: 70px 50px;
  background: #0D1A29;
  font-family: "Helvetica Neue", "Open Sans", helvetica, arial, sans-serif;
}

.timer {
  font-size: 3em;
  font-weight: 100;
  color: white;
  text-shadow: 0 0 20px #48C8FF;
  div {
    display: inline-block;
    min-width: 90px;
    span {
      color: #B1CDF1;
      display: block;
      font-size: .35em;
      font-weight: 400;
    }
  }
}
<div class="countdown timer"></div>
<div class="countdown timer"></div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Nekiy2
  • 81
  • 6
  • Whilst this may theoretically answer the question, [it would be preferable](//meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference.- I copied your codepen into the answer – mplungjan Aug 19 '20 at 13:06
  • Thank you, i will do it next time! – Nekiy2 Aug 19 '20 at 13:23
0

I made a working example with `querySelectorAll() and looping over it.

Note: You also need to change the id of the div to a class and de id selector in the css to a class selector.

function updateTimer() {
  console.log()
  future = Date.parse("June 11, 2020 11:30:00");
  now = new Date();
  diff = future - now;

  days = Math.floor(diff / (1000 * 60 * 60 * 24));
  hours = Math.floor(diff / (1000 * 60 * 60));
  mins = Math.floor(diff / (1000 * 60));
  secs = Math.floor(diff / 1000);

  d = days;
  h = hours - days * 24;
  m = mins - hours * 60;
  s = secs - mins * 60;

  document.querySelectorAll('.timer').forEach((el) => {
    el.innerHTML =
    '<div>' + d + '<span>days</span></div>' +
    '<div>' + h + '<span>hours</span></div>' +
    '<div>' + m + '<span>minutes</span></div>' +
    '<div>' + s + '<span>seconds</span></div>';
  });
    
}
setInterval('updateTimer()', 1000);
body {
  text-align: center;
  padding: 70px 50px;
  background: #0D1A29;
  font-family: "Helvetica Neue", "Open Sans", helvetica, arial, sans-serif;
}

.timer {
  font-size: 3em;
  font-weight: 100;
  color: white;
  text-shadow: 0 0 20px #48C8FF;
  div {
    display: inline-block;
    min-width: 90px;
    span {
      color: #B1CDF1;
      display: block;
      font-size: .35em;
      font-weight: 400;
    }
  }
}
<div class="timer"></div>
<br>
<div class="timer"></div>
Mark Baijens
  • 13,028
  • 11
  • 47
  • 73
  • I cannot imagine you would want TWO timers with the same end date on them on the same page!!! – mplungjan Aug 19 '20 at 12:58
  • @mplungjan I did not create the use case. Just answering the question with the details provided. It could be perhaps that he has the same timer in the footer and header. – Mark Baijens Aug 19 '20 at 13:00
  • @mplungjan it's a page that is selling a course. So I have the same section with a CTA and timer three times in the same page. – Fred Peres Aug 20 '20 at 11:56
  • @FredPeres You can still use my code. Just put the same value in all three divs – mplungjan Aug 20 '20 at 11:58
0

You can get the value from the divs

This code allows different timers on the page

Put the same time on all divs to get the same timer

function updateTimer() {
  [...document.querySelectorAll(".timer")].forEach(timer => {
    const future = Date.parse(timer.getAttribute("data-future"));
    const now = new Date();
    const diff = future - now;

    const days = Math.floor(diff / (1000 * 60 * 60 * 24));
    const hours = Math.floor(diff / (1000 * 60 * 60));
    const mins = Math.floor(diff / (1000 * 60));
    const secs = Math.floor(diff / 1000);

    h = hours - days * 24;
    m = mins - hours * 60;
    s = secs - mins * 60;

    timer.innerHTML = `<div>${days}<span>day${days===1?"":"s"}</span></div>
        <div>${h}<span>hour${h===1?"":"s"}</span></div>
        <div>${m}<span>minute${m===1?"":"s"}</span></div>
        <div>${s}<span>second${s===1?"":"s"}</span></div>`;
  })
}
setInterval('updateTimer()', 1000);
body {
  text-align: center;
  padding: 70px 50px;
  background: #0D1A29;
  font-family: "Helvetica Neue", "Open Sans", helvetica, arial, sans-serif;
}

.timer {
  font-size: 3em;
  font-weight: 100;
  color: white;
  text-shadow: 0 0 20px #48C8FF;
  div {
    display: inline-block;
    min-width: 90px;
    span {
      color: #B1CDF1;
      display: block;
      font-size: .35em;
      font-weight: 400;
    }
  }
}
<div class="timer" data-future="June 11, 2021 11:30:00"></div>
<hr/>
<div class="timer" data-future="May 2, 2021 14:30:00"></div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
-2

When working with selection by class name, here is what @CBroe was trying to say:

Array.from(document.getElementsByClassName("timer")).forEach(el => {
    el.innerHTML =
      '<div>' + d + '<span>days</span></div>' +
      '<div>' + h + '<span>hours</span></div>' +
      '<div>' + m + '<span>minutes</span></div>' +
      '<div>' + s + '<span>seconds</span></div>' ;
});
Dev Yego
  • 539
  • 2
  • 12
  • 2
    It had to be `getElementsByClassName` and you can't use forEach on a HTML-collection: https://stackoverflow.com/questions/3871547/js-iterating-over-result-of-getelementsbyclassname-using-array-foreach – Sascha Aug 19 '20 at 13:00
  • 2
    `[...document.querySelectorAll(".timer")].forEach()` – mplungjan Aug 19 '20 at 13:09