Задача №5
При заході на сайт вітати користувача або відображати повідомлення про те, скільки хвилин залишилось до початку робочого дня (початок о 8.00).
Рішення:
'use strict'
class Countdown {
intervalId
$el
countdownEl
options
constructor(cssSelector, options = {}) {
this.options = {
hours: 0,
minutes: 0,
seconds: 0,
intervalS: 1,
className: {
base: '',
target: '',
countdown: '',
},
...options,
}
this.render(cssSelector)
this.start()
}
/**
* @param {number} hours
* @param {number} minutes
*/
getCountdown(hours, minutes = 0, seconds = 0) {
const then = new Date()
then.setHours(hours, minutes, seconds)
const now = new Date()
if (now > then) then.setHours(hours + 24)
const differenceMs = then.getTime() - now.getTime()
return {
seconds: Math.floor(differenceMs / 1e3) % 60,
minutes: Math.floor(differenceMs / (1e3 * 60)) % 60,
hours: Math.floor(differenceMs / (1e3 * 60 * 60)),
}
}
formatTimeUnit(unit) {
return String(unit).padStart(2, '0')
}
updateUI() {
const {hours, minutes, seconds} = this.getCountdown(
this.options.hours,
this.options.minutes,
this.options.seconds,
)
this.countdownEl.textContent = `${this.formatTimeUnit(hours)}:${this.formatTimeUnit(minutes)}:${this.formatTimeUnit(seconds)}`
// If the timer expires, stop
if (hours === 0 && minutes === 0 && seconds === 0) this.stop()
}
start() {
if (this.intervalId) return
this.updateUI()
this.intervalId = setInterval(() => {
this.updateUI()
}, this.options.intervalS * 1e3)
}
stop() {
if (!this.intervalId) return
clearInterval(this.intervalId)
this.intervalId = null
}
render(cssSelector) {
const targetTimeEl = document.createElement('P')
targetTimeEl.className = this.options.className.target
targetTimeEl.textContent = `${this.formatTimeUnit(this.options.hours)}:${this.formatTimeUnit(this.options.minutes)}:${this.formatTimeUnit(this.options.seconds)}`
this.countdownEl = document.createElement('P')
this.countdownEl.className = this.options.className.countdown
this.$el = document.createElement('DIV')
this.$el.className = this.options.className.base
this.$el.append(this.countdownEl, targetTimeEl)
if (cssSelector) document.querySelector(cssSelector).append(this.$el)
return this.$el
}
}
// =============================================================================
new Countdown('.js-app', {
hours: 8,
intervalS: 1,
className: {
base: 'u-min-is-3200 u-p-400 u-rounded-full u-bg-natural-400 u-font-bolder u-inline-grid u-place-content-center u-aspect-square u-border-4 u-text-center',
target: 'u-text-250',
countdown: 'u-text-500',
},
})
const now = new Date()
new Countdown('.js-app', {
hours: now.getHours(),
minutes: now.getMinutes(),
seconds: now.getSeconds() + 10,
intervalS: 1,
className: {
base: 'u-min-is-3200 u-p-400 u-rounded-full u-bg-natural-400 u-font-bolder u-inline-grid u-place-content-center u-aspect-square u-border-4 u-text-center',
target: 'u-text-250',
countdown: 'u-text-500',
},
})
