This commit is contained in:
Ilya Kantor 2019-03-30 14:32:38 +03:00
parent 65671ab7ba
commit 9c3ac133e3
23 changed files with 330 additions and 273 deletions

View file

@ -0,0 +1,4 @@
Please note:
1. We clear `setInterval` timer when the element is removed from the document. That's important, otherwise it continues ticking even if not needed any more. And the browser can't clear the memory from this element and referenced by it.
2. We can access current date as `elem.date` property. All class methods and properties are naturally element methods and properties.

View file

@ -0,0 +1,9 @@
<!doctype html>
<script src="time-formatted.js"></script>
<script src="live-timer.js"></script>
<live-timer id="elem"></live-timer>
<script>
elem.addEventListener('tick', event => console.log(event.detail));
</script>

View file

@ -0,0 +1,32 @@
class LiveTimer extends HTMLElement {
render() {
this.innerHTML = `
<time-formatted hour="numeric" minute="numeric" second="numeric">
</time-formatted>
`;
this.timerElem = this.firstElementChild;
}
connectedCallback() { // (2)
if (!this.rendered) {
this.render();
this.rendered = true;
}
this.timer = setInterval(() => this.update(), 1000);
}
update() {
this.date = new Date();
this.timerElem.setAttribute('datetime', this.date);
this.dispatchEvent(new CustomEvent('tick', { detail: this.date }));
}
disconnectedCallback() {
clearInterval(this.timer); // important to let the element be garbage-collected
}
}
customElements.define("live-timer", LiveTimer);

View file

@ -0,0 +1,34 @@
class TimeFormatted extends HTMLElement {
render() {
let date = new Date(this.getAttribute('datetime') || Date.now());
this.innerHTML = new Intl.DateTimeFormat("default", {
year: this.getAttribute('year') || undefined,
month: this.getAttribute('month') || undefined,
day: this.getAttribute('day') || undefined,
hour: this.getAttribute('hour') || undefined,
minute: this.getAttribute('minute') || undefined,
second: this.getAttribute('second') || undefined,
timeZoneName: this.getAttribute('time-zone-name') || undefined,
}).format(date);
}
connectedCallback() {
if (!this.rendered) {
this.render();
this.rendered = true;
}
}
static get observedAttributes() {
return ['datetime', 'year', 'month', 'day', 'hour', 'minute', 'second', 'time-zone-name'];
}
attributeChangedCallback(name, oldValue, newValue) {
this.render();
}
}
customElements.define("time-formatted", TimeFormatted);

View file

@ -0,0 +1,12 @@
<!doctype html>
<!-- don't modify this -->
<script src="time-formatted.js"></script>
<!-- your code here: -->
<script src="live-timer.js"></script>
<live-timer id="elem"></live-timer>
<script>
elem.addEventListener('tick', event => console.log(event.detail));
</script>

View file

@ -0,0 +1,7 @@
class LiveTimer extends HTMLElement {
/* your code here */
}
customElements.define("live-timer", LiveTimer);

View file

@ -0,0 +1,34 @@
class TimeFormatted extends HTMLElement {
render() {
let date = new Date(this.getAttribute('datetime') || Date.now());
this.innerHTML = new Intl.DateTimeFormat("default", {
year: this.getAttribute('year') || undefined,
month: this.getAttribute('month') || undefined,
day: this.getAttribute('day') || undefined,
hour: this.getAttribute('hour') || undefined,
minute: this.getAttribute('minute') || undefined,
second: this.getAttribute('second') || undefined,
timeZoneName: this.getAttribute('time-zone-name') || undefined,
}).format(date);
}
connectedCallback() {
if (!this.rendered) {
this.render();
this.rendered = true;
}
}
static get observedAttributes() {
return ['datetime', 'year', 'month', 'day', 'hour', 'minute', 'second', 'time-zone-name'];
}
attributeChangedCallback(name, oldValue, newValue) {
this.render();
}
}
customElements.define("time-formatted", TimeFormatted);

View file

@ -0,0 +1,23 @@
# Live timer element
We already have `<time-formatted>` element to show a nicely formatted time.
Create `<live-timer>` element to show the current time:
1. It should use `<time-formatted>` internally, not duplicate its functionality.
2. Ticks (updates) every second.
3. For every tick, a custom event named `tick` should be generated, with the current date in `event.detail` (see chapter <info:dispatch-events>).
Usage:
```html
<live-timer id="elem"></live-timer>
<script>
elem.addEventListener('tick', event => console.log(event.detail));
</script>
```
Demo:
[iframe src="solution" height=40]