DEV Community

loading...
Cover image for (Javascript) My learning journey: Web Component

(Javascript) My learning journey: Web Component

ericchapman profile image Eric Chapman Updated on ・3 min read

If you want to miss nothing click follow and you are welcome to comments and discuss with me.

Without further ado here is a summary of my notes for today.

What is Web Component

It's a set for web platform API's that allow us to create a custom, reusable and encapsulated html tags use in web pages and web apps.

Web component do not required any special javascript libraries or framework.

Web component have 3 main building blocks:

  • Custom Element
  • Shadow DOM
  • HTML Templates

Custom Element:

Create custom HTML tags, custom class and lifecycle methods

// class inherits from HTMLElement
class customButton extends HTMLElement {
  ...
}

// To bind the new custom element
window.customElements.define('x-button', customButton)
Enter fullscreen mode Exit fullscreen mode

Lifecycle methods:

  • constructor(): Called when an instance of the element is created
  • connectedCallback(): Call every time when the element is inserted into DOM
  • disconnectedCallback(): Call every time the element is remove from the DOM
  • attributeChangedCallback(attributeName, oldValue, newValue): Call when an attribute is added, removed, updated or replaced

Shadow DOM:

  • Used for self-contained components
  • Encapsulate styles and markup
  • Create with element.attachShadow({mode:open})
  • Creates a "shadowRoot" that we can reference and interact with

HTMl Template:

  • Define the encapsulated markup of our web component
  • Template tag stores markup on page
  • Include both HTML and CSS in template
  • Use slots to add custom text

My first component

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Component</title>
</head>
<body>
    <panic-button></panic-button>
    <script src="panicButton.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

panicButton.js

class panicButton extends HTMLElement {
    constructor() {
        // Call HTMLElement constructor
        super()
        // Add some content to our component
        this.innerHTML = `Hello World`
    }
}

// Bind our component
window.customElements.define('panic-button', panicButton)
Enter fullscreen mode Exit fullscreen mode

My First Component... I guess I can do better :)
First Component

Add attribute
index.html

<panic-button message="Women and Children first"></panic-button>
Enter fullscreen mode Exit fullscreen mode

panicButton.js

class panicButton extends HTMLElement {
    constructor() {
        // Call HTMLElement constructor
        super()
        // use getAttribute to retrieved attribute
        this.innerHTML = `P A N I C - ${this.getAttribute('message')}`
    }
}

// Bind our component
window.customElements.define('panic-button', panicButton)
Enter fullscreen mode Exit fullscreen mode

Use ShadowRoot:

// Create the element with custom CSS and HTML
const template = document.createElement('template')
template.innerHTML = `
<style>
    button {
        color: white;
        background-color: red;
        font-size: 16px;
        padding: 12px;
    }
</style>
<div>
    <button></button>
</div>
`
// Create web component
class panicButton extends HTMLElement {
    constructor() {
        super()
        // Create the ShadowRoot
        this.attachShadow({mode: 'open'})
        // Add our component inside our ShadowRoot
        this.shadowRoot.appendChild(template.content.cloneNode(true))
        // Set attributes        
        this.shadowRoot.querySelector('button').innerText = `P A N I C : ${this.getAttribute('message')}`
    }
}

window.customElements.define('panic-button', panicButton)
Enter fullscreen mode Exit fullscreen mode

Launch index.html
Web Component

Use slot

<panic-button>Women and Children First</panic-button>
Enter fullscreen mode Exit fullscreen mode
// Add the <slot /> tag
const template = document.createElement('template')
template.innerHTML = `
<style>
    button {
        color: white;
        background-color: red;
        font-size: 16px;
        padding: 12px;
    }
</style>
<div>
    <button><slot /></button>
</div>
`
Enter fullscreen mode Exit fullscreen mode

Multiple-slot

<panic-button>
  <div slot="message">General Alert</div>
  <div slot="image"><img src="alter.jpg"></div>
</panic-button>
Enter fullscreen mode Exit fullscreen mode
// Add the multiple slot tag by name
const template = document.createElement('template')
template.innerHTML = `
<style>
    button {
        color: white;
        background-color: red;
        font-size: 16px;
        padding: 12px;
    }
</style>
<div>
    <button>
        <slot name="message"/>
        <slot name="image"/>
    </button>
</div>
`
Enter fullscreen mode Exit fullscreen mode

Events

class panicButton extends HTMLElement {
    constructor() {
      ...
    }
    // Add the event listener inside this lifecycle hook
    connectedCallback() {
        this.shadowRoot.querySelector('button').addEventListener('click', e => {
            alert('This is not a exercice!')
        })
    }
  }
Enter fullscreen mode Exit fullscreen mode

Conclusion

That's it for today. If you want more info about web components you can read here: https://developer.mozilla.org/en-US/docs/Web/Web_Components

If you like what I write click follow to be alert when I publish a new post on Dev.to

Discussion (0)

pic
Editor guide