Skip to content

Instantly share code, notes, and snippets.

@Tenderfeel
Last active September 4, 2018 01:33
Show Gist options
  • Save Tenderfeel/9e064aa6ec52c3e9e36514d16ab48895 to your computer and use it in GitHub Desktop.
Save Tenderfeel/9e064aa6ec52c3e9e36514d16ab48895 to your computer and use it in GitHub Desktop.
Countdown Timer
class Countdown {
constructor() {
this.limit = new Date(META.limitdate);
this.labels = ['days', 'hours', 'minutes', 'seconds'];
this.elements = {};
this.nums = {};
this.onStop = () => {};
this.labels.forEach((label) => {
this.elements[label] = window.document.querySelector(`.countdown > .nums.${label}`);
this.nums[label] = [];
});
}
start(callback) {
if (typeof callback === 'function') {
this.onStop = callback;
}
const c = this.getCache();
this.createNumElements(c);
if (c.t <= 0) {
this.stop();
} else {
this.timer = setInterval(() => {
this.countdown();
}, 1000);
}
}
static zeropad(s) {
return s < 10 ? `0${s}` : String(s);
}
getCache() {
const n = new Date();
let t = this.limit.getTime() - n.getTime();
const r = t < 0 ? 0 : t;
t = r;
const day = Countdown.zeropad(Math.floor(t / (1000 * 60 * 60 * 24)));
t -= (day * (1000 * 60 * 60 * 24));
const hour = Countdown.zeropad(Math.floor(t / (1000 * 60 * 60)));
t -= (hour * (1000 * 60 * 60));
const minute = Countdown.zeropad(Math.floor(t / (1000 * 60)));
t -= (minute * (1000 * 60));
const sec = Countdown.zeropad(Math.floor(t / 1000));
t -= (sec * 1000);
return {
t: r, days: [...day], hours: [...hour], minutes: [...minute], seconds: [...sec],
};
}
static createNum(num) {
const el = window.document.createElement('span');
el.classList.add('num');
el.innerHTML = num;
el.setAttribute('data-num', num);
return el;
}
createNumElements(c) {
this.labels.forEach((label) => {
c[label].forEach((num) => {
const el = Countdown.createNum(num);
this.elements[label].appendChild(el);
this.nums[label].push(el);
});
});
}
countdown() {
const c = this.getCache();
if (c.t <= 0) {
this.stop();
}
this.labels.forEach((label) => {
c[label].forEach((num, i) => {
this.nums[label][i].innerText = num;
this.nums[label][i].setAttribute('data-num', num);
});
});
}
stop() {
clearInterval(this.timer);
this.labels.forEach((label) => {
this.elements[label] = null;
this.nums.forEach((num, i) => {
this.nums[label][i] = null;
});
});
this.onStop();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment