özgür kuş
özgür kuş

Reputation: 101

How to use same JavaScript widget 2 times in same webpage?

I found a widget on Codepen and implement it on my website. But, I want to use it twice in 2 different pages in my website. When I copy the HTML to other page, it is not working. I know i have to make some changes in my code but I'm really not good with JS.

Can you show me how to work the second widget?

var countDate = new Date("Jan 01, 2021 00:00:00").getTime();

function newYear() {
  var now = new Date().getTime();
  gap = countDate - now;

  var second = 1000;
  var minute = second * 60;
  var hour = minute * 60;
  var day = hour * 24;

  var d = Math.floor(gap / day);
  var h = Math.floor((gap % day) / hour);
  var m = Math.floor((gap % hour) / minute);
  var s = Math.floor((gap % minute) / second);

  document.getElementById("day").innerText = d;
  document.getElementById("hour").innerText = h;
  document.getElementById("minute").innerText = m;
  document.getElementById("second").innerText = s;
}

setInterval(function() {
  newYear();
}, 1000);
.countdown {
  display: flex;
  justify-content: center;
}

.countdown .separator {
  font-weight: 400;
}

.countdown div {
  position: relative;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
  color: #45deb0;
  margin: 0 -15px;
  font-size: 3em;
  font-weight: 500;
}

.countdown div:before {
  content: "";
  position: absolute;
  bottom: -10px;
  left: 0;
  width: 100%;
  height: 35px;
  color: #45deb0;
  font-size: 0.35em;
  line-height: 35px;
  font-weight: 300;
}

.countdown div#day:before {
  content: "Dagen";
}

.countdown div#hour:before {
  content: "Uren";
}

.countdown div#minute:before {
  content: "Uren";
}

.countdown div#second:before {
  content: "Seconden";
}
<div class="countdown">
  <div id="day">na</div>
  <div class="separator"><span>:</span></div>
  <div id="hour">na</div>
  <div class="separator"><span>:</span></div>
  <div id="minute">na</div>
  <div class="separator"><span>:</span></div>
  <div id="second">na</div>
</div>


<p>How can I make the second countdown widget(the one in bottom) work with same codes?</p>

<div class="countdown">
  <div id="day">na</div>
  <div class="separator"><span>:</span></div>
  <div id="hour">na</div>
  <div class="separator"><span>:</span></div>
  <div id="minute">na</div>
  <div class="separator"><span>:</span></div>
  <div id="second">na</div>
</div>

Upvotes: 1

Views: 174

Answers (2)

Dan Knights
Dan Knights

Reputation: 8368

You're using duplicate id's and document.getElementById returns a single element. Use class instead and loop through them:

var countDate = new Date("Jan 01, 2021 00:00:00").getTime();

function newYear() {
  var now = new Date().getTime();
  gap = countDate - now;

  var second = 1000;
  var minute = second * 60;
  var hour = minute * 60;
  var day = hour * 24;

  var d = Math.floor(gap / day);
  var h = Math.floor((gap % day) / hour);
  var m = Math.floor((gap % hour) / minute);
  var s = Math.floor((gap % minute) / second);

  var dayDivs = document.querySelectorAll(".day");
  var hourDivs = document.querySelectorAll(".hour");
  var minuteDivs = document.querySelectorAll(".minute");
  var secondDivs = document.querySelectorAll(".second");

  for (let i = 0; i < dayDivs.length; i++) {
    dayDivs[i].innerText = d;
    hourDivs[i].innerText = h;
    minuteDivs[i].innerText = m;
    secondDivs[i].innerText = s;
  }
}

setInterval(function() {
  newYear();
}, 1000);
.countdown {
  display: flex;
  justify-content: center;
}

.countdown .separator {
  font-weight: 400;
}

.countdown div {
  position: relative;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
  color: #45deb0;
  margin: 0 -15px;
  font-size: 3em;
  font-weight: 500;
}

.countdown div:before {
  content: attr(data-time);
  position: absolute;
  bottom: -10px;
  left: 0;
  width: 100%;
  height: 35px;
  color: #45deb0;
  font-size: 0.35em;
  line-height: 35px;
  font-weight: 300;
}
<div class="countdown">
  <div class="day" data-time="Dagen">na</div>
  <div class="separator"><span>:</span></div>
  <div class="hour" data-time="Uren">na</div>
  <div class="separator"><span>:</span></div>
  <div class="minute" data-time="Uren">na</div>
  <div class="separator"><span>:</span></div>
  <div class="second" data-time="Seconden">na</div>
</div>


<p>How can I make the second countdown widget(the one in bottom) work with same codes?</p>

<div class="countdown">
  <div class="day" data-time="Day">na</div>
  <div class="separator"><span>:</span></div>
  <div class="hour" data-time="Hour">na</div>
  <div class="separator"><span>:</span></div>
  <div class="minute" data-time="Minute">na</div>
  <div class="separator"><span>:</span></div>
  <div class="second" data-time="Second">na</div>
</div>

Upvotes: 3

Lawrence Cherone
Lawrence Cherone

Reputation: 46602

Ideally, to make it actually reusable and customisable it would be better to rename the function to countdown() and simply pass in the element for the block of DOM, then use data-* attribute on the elements to define the and labels and separator.

Also simplify the CSS, so things fit, you are only centring some text it does not really need flex.

function countdown(elm) {
  var countDate = new Date(elm.getAttribute('data-to') || new Date).getTime();

  var now = new Date().getTime();
  var gap = countDate - now;

  var second = 1000;
  var minute = second * 60;
  var hour = minute * 60;
  var day = hour * 24;

  var result = {
    day: Math.floor(gap / day),
    hour: Math.floor((gap % day) / hour),
    minute: Math.floor((gap % hour) / minute),
    second: Math.floor((gap % minute) / second)
  }
  
  Object.keys(result).forEach((key) => {
    var sector = elm.getElementsByClassName(key)[0]
    sector.innerText = (result[key] || 0) + sector.getAttribute('data-label') || ''
  })
}

document.querySelectorAll('.countdown').forEach((elm) => setInterval(() => countdown(elm), 1000));
.text-center {
  text-align: center;
}

.countdown .separator {
  font-weight: 400;
}

.countdown div {
  display: inline-block;
  height: 100px;
  line-height: 100px;
  color: #45deb0;
  font-size: 2em;
  font-weight: 500;
}
<div class="text-center">
  <div class="countdown" data-to="Jan 01, 2021 00:00:00">
    <div class="day">na</div>
    <div class="separator"><span>:</span></div>
    <div class="hour">na</div>
    <div class="separator"><span>:</span></div>
    <div class="minute">na</div>
    <div class="separator"><span>:</span></div>
    <div class="second">na</div>
  </div>

  <p>How can I make the second countdown widget(the one in bottom) work with same codes?</p>

  <div class="countdown" data-to="Jan 01, 2022 00:00:00">
    <div class="day" data-label="days, "></div>
    <div class="hour" data-label="hours, "></div>
    <div class="minute" data-label="minutes, "></div>
    <div class="second" data-label="seconds"></div>
  </div>

  <div class="countdown" data-to="Jan 01, 2023 00:00:00">
    <div class="day" data-label="d - "></div>
    <div class="hour" data-label="h - "></div>
    <div class="minute" data-label="m - "></div>
    <div class="second" data-label="s"></div>
  </div>

</div>

Upvotes: 1

Related Questions