Challenge - Custom element
Build a component structure with custom elements and shadow DOM.
Custom element
In this challenge you will write a custom element: the <bookmark-card> tag. First you define a class that extends HTMLElement.
To register it you call customElements.define('bookmark-card', BookmarkCard). The first argument is the tag name and must contain a hyphen.
Among the lifecycle callbacks, connectedCallback fires when the element is attached to the document. Here you open a shadow root with this.attachShadow({ mode: 'open' }) and write the content into it, keeping styles from leaking out.
Shadow DOM and lifecycle
To isolate a custom element's content from the outside you use shadow DOM. this.attachShadow({ mode: 'open' }) attaches a shadow root to the element.
You write HTML into the returned shadow root's innerHTML; this content stays separate from the outer document and does not leak styles.
connectedCallback is a lifecycle callback: it runs every time the element is added to the DOM. Opening the shadow root and writing the content here is the most common pattern.
Exercise Write the BookmarkCard element
Write a BookmarkCard class that extends HTMLElement and has a connectedCallback method. Inside it open a shadow root with this.attachShadow({ mode: 'open' }) and write a paragraph into its innerHTML. Then register it with customElements.define('bookmark-card', BookmarkCard).
Show example solution
'open' }) and set shadow.innerHTML. At the end add customElements.define('bookmark-card', BookmarkCard);.
Example solution:
class BookmarkCard extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = '<p>Bookmark</p>';
}
}
customElements.define('bookmark-card', BookmarkCard);
Test yourself
-
How do you register a custom element?
customElements.define('bookmark-card', BookmarkCard);- document.registerElement
- customElements.define
- window.defineElement
- HTMLElement.register
Show answer
customElements.define — Correct! customElements.define takes the tag name and the class.
-
Register the element
class BookmarkCard extends HTMLElement { constructor() { super(); } } ____;Show answer
class BookmarkCard extends HTMLElement { constructor() { super(); } } customElements.define('bookmark-card', BookmarkCard);