31. Countdown Timer - Start and Pause

HTML

1
<div id="app" aria-live="polite"></div>

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* For this project, we’re going to add two always-present buttons
below the countdown in the timer.
One button will say Start when the timer is stopped, and Pause when it’s running.
Clicking it starts or stops the timer without resetting the time. */

const timeValue = 120;
let timer;
const Rue = function (selector, options) {
this.elem = document.querySelector(selector);
this.data = options.data;
this.template = options.template;
};
Rue.prototype.render = function () {
this.elem.innerHTML = this.template(this.data);
};
const formatTime = function (time) {
let minutes = Math.floor(time / 60);
let seconds = time % 60;
return `${(minutes.toString())}:${seconds.toString().padStart(2,'0')}`;
}
const startTimer = function (e) {
if (!e.target.hasAttribute('data-start-timer')) return;
if (app.data.time < 1) {
app.data.time = timeValue;
}
app.data.paused = false;
app.render();
stopTimer();
timer = setInterval(countdown, 1000);
};
const countdown = function () {
app.data.time--
if (app.data.time < 1) {
stopTimer();
app.data.paused = true;
}
app.render();
}
const stopTimer = function () {
clearInterval(timer)
}
const pauseTimer = function (e) {
if (!e.target.hasAttribute('data-pause-timer')) return;
stopTimer();
app.data.paused = true;
app.render();
}
const restartTimer = function (e) {
if (!e.target.hasAttribute('data-restart-timer') || app.data.time === timeValue) return;
stopTimer();
app.data.time = timeValue;
app.data.paused = false;
app.render();
timer = setInterval(countdown, 1000);
}
const clickHandler = function (e) {
startTimer(e);
restartTimer(e);
pauseTimer(e);
}
const app = new Rue('#app', {
data: {
time: timeValue,
paused: true,
altMsg: true
},
template: function (props) {
if (!props) return;
if (props.time === 0 && props.altMsg) {
let html = `<h2>It's over, start again:</h2><button data-restart-timer class="button stop">Restart</button></div>`
return html;
}
let html = `<h2>You've got only <span class="counter">${formatTime(props.time)}</span> seconds!</h2>` +
(props.paused ? `<div class="buttons-container"><button data-start-timer class="button start">Start</button>` : `<div class="buttons-container"><button data-pause-timer class="button start">Pause</button>`) + `<button data-restart-timer class="button stop">Restart</button></div>`
return html;
}
})
app.render();
document.addEventListener('click', clickHandler);