In JavaScript, an HTML element is represented by the HTMLElement interface. Accordingly, implementing this interface in JavaScript, we can create our own classes that will represent the html elements, and then use them.
Example:
<html> <text-element></text> </html>
So, in order to define a class that will represent an HTML element, we just need to create a class that implements
HTMLElement interface:
class TextElement extends HTMLElement { }
The second important point is that we need to register our custom HTML element so that the browser knows that there is such element. To do this, use the built-in function:
class TextElement extends HTMLElement { } customElements.define(name, constructor, options);
name – the name of the custom html element that will represent the JavaScript class. Important: The name must contain a hyphen.
constructor – a constructor (essentially a JavaScript class) that represents a custom HTML element.
options – optional parameter – an object that sets up a custom HTML element. At the moment he supports one parameter – extends. It defines the name of the inline html element that is used to create custom HTML element.
class TextElement extends HTMLElement { } customElements.define('text-element', TextElement);
But for now, the “text-element” custom element does nothing. Let’s add some primitive task to it. Let him prints out some greeting.
class TextElement extends HTMLElement { constructor() { super();//ensures that our class inherits all methods, attributes, and properties of the interfaceHTMlElement. } }
In the constructor, we can assign the basic logic of our element:
class TextElement extends HTMLElement { constructor() { super(); let welcome = "Good morning"; const hour = new Date().getHours(); if (hour > 17) { welcome = "Good evening"; } else if (hour > 12) { welcome = "Good afternoon"; } this.innerText = welcome; } } customElements.define('text-element', TextElement);
In the constructor, we get the current time and, depending on the current hour, we determine the greeting text. Since our class uses the HTMLElement interface, then accordingly we can use the standard for html elements in it properties.
Adding methods
As with regular classes, we can allocate methods in element classes and call them later:
class TextElement extends HTMLElement { constructor() { super(); let welcome = "Good morning"; const hour = new Date().getHours(); if (hour > 17) { welcome = "Good evening"; } else if (hour > 12) { welcome = "Good afternoon"; } this.innerText = welcome; } showTime() {//method that returns the current hour console.log(new Date().toTimeString()); } } customElements.define('text-element', TextElement); // get the element const text = document.getElementById("text"); // on click, we call its showTime method hello.addEventListener("click", () => text.showTime());
Life cycle of a custom html element
The custom HTML element has its own life cycle, which is described by the following methods:
connectedCallback – called every time a custom html element is added to the DOM.
disconnectedCallback – called every time the custom html element is removed from the DOM.
adoptedCallback – called every time the custom html element is moved to a new element.
attributeChangedCallback – called whenever an attribute is changed (added, changed, or removed) custom html element.
connectedCallback() { this.style.color = "red"; }
Adding attributes
<text-element c="red"></text-element>
connectedCallback() { if (this.hasAttribute("c")) { this.style.color = this.getAttribute("c"); } }
CSS styling
Styling an element with CSS is the same as styling any other element:
this.style.cursor = "pointer" this.innerText = welcome;