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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
const timeValue = 120; let timer; const handler = function (instance) { return { get: function (obj, prop) { if (['[object Object]', '[object Array]'].indexOf(Object.prototype.toString.call(obj[prop])) > -1) { return new Proxy(obj[prop], handler(instance)); } return obj[prop]; instance.render(); }, set: function (obj, prop, value) { obj[prop] = value; instance.render(); return true; }, deleteProperty: function (obj, prop) { delete obj[prop]; instance.render(); return true; } } } const Rue = function (selector, options) { const _this = this; _this.elem = document.querySelector(selector); const _data = new Proxy(options.data, handler(this)); _this.template = options.template; Object.defineProperty(this, 'data', { get: function () { return _data; }, set: function (data) { _data = new Proxy(data, handler(_this)); _this.render(); return true; } }) }; 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; stopTimer(); timer = setInterval(countdown, 1000); }; const countdown = function () { app.data.time-- if (app.data.time < 1) { stopTimer(); app.data.paused = true; } } const stopTimer = function () { clearInterval(timer) } const pauseTimer = function (e) { if (!e.target.hasAttribute('data-pause-timer')) return; stopTimer(); app.data.paused = true; } 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; 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);
|