// ⭐️ 1️⃣ 宣告自訂元素
class MyComponent extends HTMLElement {
// constructor
constructor() {
super();
// ⭐️ 2️⃣ 建立 shadow DOM
this.attachShadow({ mode: 'open' }); // returns a reference to this.shadowRoot
// ⭐️ 3️⃣ 建立樣板 4️⃣ 複製樣板內容到 shadow root
this.shadowRoot.innerHTML = `
<style> ... </style>
<div class="container"> ... </div>
`;
}// end of constructor()
}// end of MyComponent
// ⭐️ 5️⃣ 註冊標籤 ╭──tag name──╮ ╭─ class ─╮
window.customElements.define('my-component', MyComponent);
📁 自訂內建元素 (customized built-in element)
// ⭐️ customized built-in element
class FancyButton extends HTMLButtonElement {
constructor(){...}
}
// ⭐️ register new tag
// ╭─── name ───╮ ╭─ class ─╮ ╭───────⭐️────────╮
customElements.define('fancy-button', FancyButton, {extends: 'button'});
// ⭐️ autonomous custom element ---------------
// autonomous:獨立存在的(非內建的,如:HTMLButtonElement 等)
class MyComponent extends HTMLElement {
// constructor
constructor() {
// tell HTMLElement to initialize itself.
super();
// get `width`, `height` attributes
const height = this.getAttribute('height') || '100px';
const width = this.getAttribute('width') || '100px';
// ...
}
// connected to document
connectedCallback() {
// attach shadow root
let root = this.attachShadow({mode: 'open'});
// ⭐️ clone nodes from <template>
let clone = tmpl.content.cloneNode(true);
root.append( clone );
// ...
}
// template HTML
static template(height, width) {
return `
<style>
.placeholder {
background-color: pink;
width: ${height};
height: ${width};
}
</style>
<div class='placeholder'>Placeholder</div>
`;
}
}
// ⭐️ register <my-component>
// ⭐️⭐️ custom element names must contain a "hyphen".
// ╭──tag name──╮ ╭─ class ─╮
customElements.define('my-component', MyComponent);
📁 JS:定義並宣告
// ⭐️ customized built-in element
class FancyButton extends HTMLButtonElement {
constructor(){...}
}
// ⭐️ register new tag
// ╭─── name ───╮ ╭─ class ─╮ ╭───────⭐️────────╮
customElements.define('fancy-button', FancyButton, {extends: 'button'});
📁 HTML:使用自訂內建元素 (customized built-in element)
<!-- ⭐️ customized built-in element -->
<!-- ╭─── name ───╮ -->
<button is="fancy-button">some text</button>
📁 JS:使用自訂內建元素
// ⭐️ 方法ㄧ: `new MyComponent()`
let button = new FancyButton();
// ⭐️ 方法二: `document.createElement('my-component')`
// ╭─tag──╮ ╭────────⭐️────────╮
let button = document.createElement('button', {is: 'fancy-button'});
// customize
button.textContent = 'Fancy button!';
button.disabled = true;
// add to DOM tree
document.body.appendChild(button);
(Google)
📗 JS.info ⟩
Building Native Web Components (2021)
JavaScript: The Definitive Guide (15.6 Web Components)