Untitled
unknown
plain_text
a month ago
5.9 kB
2
Indexable
Never
<script> class Timer { constructor(selectors) { this.sec = 0; this.min = 0; this.running = false; this.startTime = 0; // Timestamp. this.timerTime = [0, 0]; // Minutes and seconds. this.timerCastInterval; this.selectors = { wrapper: '', inputMin: '', inputSec: '', btnStart: '', btnStop: '', timerPreview: '', timerPreviewCast: '' }; this.uiElements = { wrapper: null, inputMin: null, inputSec: null, btnStart: null, btnStop: null, timerPreview: null, timerPreviewCast: null, } this.setInterface(selectors); this.addInterfaceListeners(); } setInterface(selectors) { const that = this; this.selectors = {...this.selectors, ...selectors}; Object.keys(this.selectors).forEach(key => { if (that.selectors[key].length > 0) { const el = document.querySelector(that.selectors[key]); if (el !== null) { that.uiElements[key] = el; } } }); } addInterfaceListeners() { const that = this; // Start. if (this.uiElements.btnStart !== null) { this.uiElements.btnStart.addEventListener('click', function () { if (!that.isRunning()) { that.start(); } }); } // Stop. if (this.uiElements.btnStop !== null) { this.uiElements.btnStop.addEventListener('click', function () { if (that.isRunning()) { that.stop(); } }); } }; setSec(sec) { if (this.isRunning() || isNaN(sec)) { return; } this.sec = this.sanitizeSec(sec); } setMin(min) { if (this.isRunning() || isNaN(min)) { return; } this.min = this.sanitizeMin(min); } sanitizeSec(sec) { if (isNaN(sec)) { sec = 0; } sec = parseInt(sec); if (sec < 0) { sec = 0; } if (sec > 59) { sec = 59; } return sec; } sanitizeMin(min) { if (isNaN(min)) { min = 0; } min = parseInt(min); if (min < 0) { min = 0; } return min; } isRunning() { return this.running; } getCurrentTime() { // Timestamp. return Math.floor(new Date().getTime() / 1000); } setStartTime() { this.startTime = this.getCurrentTime() - this.sec - this.min * 60; } resetStartTime() { this.startTime = 0; } manageDynamicClasses(action) { // Wrapper class. if (this.uiElements.wrapper !== null) { const toAdd = action === 'stop' ? 'timer-stopped' : 'timer-running'; const toRemove = action === 'stop' ? 'timer-running' : 'timer-stopped'; this.uiElements.wrapper.classList.add(toAdd); this.uiElements.wrapper.classList.remove(toRemove); } if (action === 'start') { this.uiElements.btnStart.disabled = true; this.uiElements.inputMin.disabled = true; this.uiElements.inputSec.disabled = true; this.uiElements.btnStop.disabled = false; } if (action === 'stop') { this.uiElements.btnStart.disabled = false; this.uiElements.inputMin.disabled = false; this.uiElements.inputSec.disabled = false; this.uiElements.btnStop.disabled = true; } } start() { if (this.isRunning()) { return; } this.updateTimeFromInputs(); this.setStartTime(); this.updateTime(); this.cast(); this.manageDynamicClasses('start'); this.running = true; } stop() { this.updateTime(); this.running = false; this.resetStartTime(); this.stopCast(); this.manageDynamicClasses('stop'); this.updateTimeInputs(); } updateTime() { if (!this.isRunning()) { return; } const diffSeconds = this.getCurrentTime() - this.startTime; this.min = Math.floor(diffSeconds / 60); this.sec = diffSeconds % 60; } getTimerTime() { this.updateTime(); return [this.min, this.sec]; } formatTimeNumber(number) { return number < 10 ? '0' + number : number; } getFormattedTimerTime() { const time = this.getTimerTime(); const minutesFormatted = this.formatTimeNumber(time[0]); const secondsFormatted = this.formatTimeNumber(time[1]); return minutesFormatted + ':' + secondsFormatted; } updateTimeFromInputs() { const sec = this.uiElements.inputSec.value; const min = this.uiElements.inputMin.value; if (sec.length > 0 && !isNaN(sec)) { this.setSec(sec); this.uiElements.inputSec.value = this.formatTimeNumber(this.sanitizeSec(sec)); } if (min.length > 0 && !isNaN(min)) { this.setMin(min); this.uiElements.inputMin.value = this.formatTimeNumber(this.sanitizeMin(min)); } } updateTimeInputs() { this.uiElements.inputMin.value = this.formatTimeNumber(this.min); this.uiElements.inputSec.value = this.formatTimeNumber(this.sec); } cast() { const that = this; this.timerCastInterval = setInterval(function () { const time = that.getFormattedTimerTime(); if (that.uiElements.timerPreview !== null) { that.uiElements.timerPreview.innerHTML = time; } }, 100); } stopCast() { clearInterval(this.timerCastInterval); } } document.addEventListener("DOMContentLoaded", function () { window.timer = new Timer({ wrapper: '.js-timer-wrapper', inputMin: '.js-timer-min', inputSec: '.js-timer-sec', btnStart: '.js-timer-start', btnStop: '.js-timer-stop', timerPreview: '.timer-preview', timerPreviewCast: '' }); }); </script> <div class="js-timer-wrapper"> <div class="timer-preview">00:00</div> <input type="text" value="" name="timer-min" class="js-timer-min" placeholder="min"> <input type="text" value="" name="timer-sec" class="js-timer-sec" placeholder="sec"> <button class="js-timer-start">Start</button> <button class="js-timer-stop">Stop</button> </div>
Leave a Comment