// define new custom element
customElements.define(
'web-component', // โญ๏ธ HTML tag name, must have "-"โ๏ธ
class extends HTMLElement { ... } // โญ๏ธ must extend `HTMLElement`โ๏ธ
);
custom elements render as inline elements by default.
<p>
The document has one marble:
<inline-circle size="3em" color="red"></inline-circle>. <br>
The HTML parser instantiates two more marbles:
<inline-circle size="2em" color="blue"></inline-circle>
<inline-circle color="green"></inline-circle>.
<hr>
How many marbles does the document contain now?
</p>
๐ JS
// define custom element:
customElements.define("inline-circle", class extends HTMLElement {
// ๐ธ when <inline-circle> inserted into document.
connectedCallback() {
// styles for circles
// โญ๏ธ demo only: don't do this in real apps.
this.style.display = "inline-block";
this.style.borderRadius = "50%";
this.style.border = "solid black 1px";
this.style.transform = "translateY(10%)";
// default size
if (!this.size) this.size = "0.8em";
}
// ๐ธ observed attributesstatic
get observedAttributes() { return ["size", "color"]; }
// ๐ธ when one of the attributes listed above changes.
attributeChangedCallback(name, oldValue, newValue) {
switch (name) {
case "size":
this.style.width = newValue;
this.style.height = newValue;
break;
case "color":
this.style.backgroundColor = newValue;
break;
}
}
// ๐ธ getter/setter for element's attributes.
get size() { return this.getAttribute("size"); }
set size(size) { this.setAttribute("size", size); }
get color() { return this.getAttribute("color"); }
set color(color) { this.setAttribute("color", color); }
});
We can create our tags by using the CustomElementRegistry object (window.customElements).
custom element names must contain a hyphenโ
๐ customElements.define()
Custom elements cannot be self-closing because HTML only allows a few elements to be self-closing. Always write a closing tag
(<custom-element></custom-element>)
๐ Google โฉ Custom Elements
// โญ๏ธ custom tag <my-component>
// โญ๏ธ custom element names must contain a "hyphen".
customElements.define('my-component', MyComponent);
Supporting Class
To create a custom element, we need to tell the browser several details about it: how to show it, what to do when the element is added or removed to page, etc.
class MyComponent extends HTMLElement {
constructor() {
super();
// ...
}
// triggered when added to the document
connectedCallback() {}
// triggered when removed from the document
disconnectedCallback() {}
// attribute names to monitor for changes
static get observedAttributes() {
return [ /* ... */ ];
}
// triggered when one of attributes listed above is modified.
// doesnโt trigger for unlisted attributes (for performance reasons).
attributeChangedCallback(name, oldValue, newValue) {}
// called when moved to a new document
// happens in document.adoptNode, very rarely used
adoptedCallback() {}
// other methods and properties ...
}