browser ⟩ web components ⟩ implement ⟩ custom elements ⟩ lifecycle methods
⭐️ 重點 📘 手冊 📗 參考 💈範例
constructor ()
an instance of custom element is created or upgraded .
connectedCallback ()
custom element is appended into/moved in a document.
disconnectedCallback ()
custom element is removed from the document.
attributeChangedCallback (attrName , oldVal , newVal )
one of the custom element’s attributes is added /removed /changed .
observed attributes are specified with static get observedAttributes()
.
adoptedCallback ()
custom element is moved to a new document .
💾 web component life cycle
📁 HTML
Copy <div id="parent">
<!-- web component -->
<my-component text="my personal text"></my-component>
</div>
<button id="button" onclick="removeElement()">Remove Element</button>
📁 JS
Copy // ⭐️ 1. custom web component
class MyComponent extends HTMLElement {
constructor(){
// debug info
console.log(`🐣 contructed ...`);
// tell HTMLElement to initialize itself
super();
// variables
const text = this.getAttribute('text') || 'Loren Ipsum';
const size = randomInt(12, 50); // random font size
// create element
const elem = document.createElement('template');
elem.innerHTML = MyComponent.template(text, size);
// add to UI
this.appendChild(document.importNode(elem.content, true));
}
// HTML tempalte
static template(text, size) {
return `
<div style="font-size:${size}px">
${text} (font-size: ${size})
</div>
`;
}
/* -------- life-cycle triggers -------- */
connectedCallback() { console.log(`🔌 connected ...`); }
disconnectedCallback() { console.log(`❌ disconnected ...`); }
attributeChangedCallback(attrName, oldVal, newVal) {
console.log(`✏️ attribute "${attrName}" changed: ${oldVal} ➝ ${newVal}`);
}
/*
To get the attributeChangedCallback() method to work correctly,
we must add the static method observedAttributes() and
return the properties that we want to observe.
*/
static get observedAttributes() {
return ['text'];
}
/* --------- set/get `text` ---------- */
set text(val) { this.setAttribute(`text`, val ?? ``); }
get text() { return this.getAttribute('text'); }
}
// ⭐️ 2. custom tag <my-component>
// ⭐️⭐️ custom element names must contain a "hyphen".
customElements.define('my-component', MyComponent);
/* -------- button -------- */
function removeElement() {
const div = $('#parent');
const element = $('my-component');
const button = $('#button');
div.removeChild(element);
button.disabled = true;
}
/* -------- helpers -------- */
// $ ⭐️
function $(selector, parent = document){
return parent.querySelector(selector);
}
// random integer between a and b
function randomInt(a, b){
return Math.floor((Math.random() * (b - a + 1)) + a)
}