Reusable HTML Components using vanilla JavaScript

As developers, we are aware of the benefits of reusing code wherever possible. The foundation of Javascript libraries and frameworks like React, Angular, Vue, and others is the realization that it makes no sense to write repeated code, just create a reusable web component and use it across the pages.

With the introduction of Web Components, it is now possible to create reusable components without utilizing Javascript Libraries and Framework, which was previously only possible with Javascript Libraries and Frameworks.

Web Components is a suite of different technologies allowing you to create reusable custom elements. These elements' functionality is isolated from the rest of your code.

The following actions can lead to reusable components.

In this article, we're going to focus on custom elements.

Custom Elements

It can be a little trickier to construct custom elements and put them into our HTML using shadow DOM and HTML templates, but it is really simple and easy to use custom Elements.

We first create a custom element and register our custom elements on the page, which returns information on what custom elements are registered.

To register our custom element we use CustomElements.define a method which takes two arguments:

  • A string representing the name of the element which must be in kebab-case(they require a dash to be used in them).

  • A class that defines the behavior of the element.

The example of registering a custom element is:

CustomElements.define("main-nav",Nav);

The element is called main-nav and its class object is Nav:

Now let's create a simple custom element:

class Nav extends HTMLElement {
  constructor() {
    super();
  }
  connectedCallback() {
    this.innerHTML = `
        <nav id = "nav">
          <div class="navigation">
          <a href = "/index.html">
          <img  src="./assets/images/logo.png" alt="logo" />
          <a/>
          <ul>
            <li><a href="./index.html">Home</a></li>
            <li><a href="./about.html">About Us</a></li>
            <li><a href="./contact.html">Contact</a></li>
            <li><a href="./gallery.html">Gallery</a></li>
            <li><a href="./blog.html">Blog</a></li>
          </ul>
        </div>
        <div class="icons">
          <p><i class="ri-facebook-fill"></i></p>
          <p><i class="ri-twitter-fill"></i></p>
          <p><i class="ri-instagram-fill"></i></p>
        </div>
      </nav>
        `;
  }
}

This is a simple nav element that we can reuse in our different pages like About, Contact, Gallery, Blog, and so on.

Let's register our class to use on our page.

customElements.define("main-nav", Nav);

Now we can use custom elements in our HTML pages.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Custom Element Example</title>
  </head>
<body>
<!-- page content  -->
    <main-nav></main-nav>
</body>
</html>

We have used connectedCallback it in our class, let's understand what that is.

You can define several different callbacks inside a custom element's class definition, which fire at different points in the element's lifecycle:

There are four lifecycle callbacks that we can use to fire the element's lifecycle.

  • connectedCallback: This will invoke each time the custom element is appended to the document and may happen before the element's contents have been fully parsed.

  • disconnectedCallback: Invoked each time the custom element is disconnected from the document's DOM.

  • adoptedCallback: Invoked each time the custom element is moved to a new document.

  • attributeChangedCallback: Invoked each time one of the custom element's attributes is added, removed, or changed. Which attributes to notice a change for is specified in a static get observedAttributes method.

This was the basic understanding of web components using custom elements, you can be extended this knowledge by using different lifecycle callbacks to accept data from HTML and use them in our custom element.

You can use different libraries like lit-html, FASTELEMENT, slim.js, and others as per your will to achieve web components with a higher level of abstraction.