// 1. define new elementclassLiveTimerextendsHTMLElement {/* ---------- life cycle callbacks ---------- */// triggers when element is added to page// (or when HTML parser detects it)connectedCallback() {this.render();
// 1. define new element
class TimeFormatted extends HTMLElement {
/* ---------- life cycle callbacks ---------- */
constructor(){
super();
this.initialized = false;
}
// triggers when <time-formatted> element is added to page
// (or when HTML parser detects it)
connectedCallback() {
this.render();
this.initialized = true;
}
// observed attributes
static get observedAttributes() { // (3)
return [
'datetime', 'year', 'month', 'day',
'hour', 'minute', 'second', 'time-zone-name'
];
}
attributeChangedCallback(name, oldValue, newValue) {
// re-render when attributes changed
this.render();
// if(this.initialized) log(`${name} = ${newValue}`);
}
/* ---------- helper methods ---------- */
render() {
// let date = new Date(this.attr('datetime') || Date.now());
let date = new Date();
// built-in Intl.DateTimeFormat formatter
let formatter = new Intl.DateTimeFormat("default", {
year : this.attr('year'),
month : this.attr('month'),
day : this.attr('day'),
hour : this.attr('hour'),
minute: this.attr('minute'),
second: this.attr('second'),
timeZoneName: this.attr('time-zone-name'),
});
// show a nicely formatted time.
// ⭐️ 注意:這裡設定的東西屬於 light DOM❗️
this.innerHTML = formatter.format(date);
}
}
// 2. register new element
customElements.define("time-formatted", TimeFormatted);