web-components

Web components: should I do it?

by

danazkari

For quite a while I’ve been following along the web components spec. The first drafts I felt it a little bit awkward and weird, a LOT of boilerplate code was needed just to define one, so projects like Polymer made ┬áTON of sense to use.

Web components is actually a collection of web standards, ShadowDOM, CustomElements, HTML Imports and HTML Templates. But, this doesn’t mean we need to use them all. Personally, I found ShadowDOM and CustomElments to be the most useful ones, just because they adapt easily into any framework or architecture.

Now, with ES6 in it’s best, we have the opportunity to define web components in a very fashionable way… Just look at this very simple (and super sexy) piece of code:

class DeepThought extends HTMLElement {

}

document.registerElement('deep-thought', DeepThought);

That’s it-ish! With those lines of code, you can create new HTML elements of type DeepThought.

<deep-thought></deep-thought>

Now, this element is kinda dumb… doesn’t do anything special just yet, for that we have to add handlers to 4 special callbacks that come bundled with that extends call, those are:

  • createdCallback
  • attachedCallback
  • detachedCallback
  • attributeChangedCallback

This is known as the lifecycle of a web component.

Bear in mind, if we’re talking about web components with ES6, createdCallback == constructor, if you define a constructor for the class, it won’t ever be called, because of how the HTMLElement class works.

class DeepThought extends HTMLElement {
    createdCallback() {
        this._answer = 42;
        this._question = undefined;

        let shadowDOM = this.createShadowRoot();
        shadowDOM.innerHTML = `
            <style>
                button {
                   border-radius: 3px;
                   max-wdith: 150px;
                   padding: 10px;
                   box-sizing: border-box;
                   background: #34495e;
                   border: 0;
                   color: #fff;
                }
            </style>
            <button>Get THE answer</button>
        `;

        this._getAnswerButton = this.shadowRoot.querySelector('button');
    }

    __getAnswer() {
        alert(this._answer);
    }

    attachedCallback() {
        this._getAnswerButton
            .addEventListener('click', this.__getAnswer.bind(this), false);
    }

    detachedCallback() {
        this._getAnswerButton
            .removeEventListener('click', this.__getAnswer.bind(this), false);
    }
}

document.registerElement('deep-thought', DeepThought);

And so, as you can see now we have a custom HTML, encapsulated thanks to Shadow DOM, with custom behavior and with pure JavaScript.

If you add polyfills, then you’re pretty darn close to being able to use web components in a production app.

Key phrase pretty darn close, you still get no actual support for Shadow DOM, you get a Shady DOM for those browsers like Safari, and with Safari you get NO support for the attributeChangedCallback which makes life harder for us…

The solution? Could be to use things like the Polymer Project.

These guys at Polymer have it all figured out, and by using their framework, your life becomes a lot easier. Best of all? You get standard Web Components in return, compatible with whoever wants to use them!!!

Want to share your brand new web components? CustomElements.io has your back, there are hundreds and hundreds already.

That’s as far as I’ve come with this subject, if you have any questions or wanna share your thoughts, please feel free to leave them below.

Till next time!

Comments

comments

Powered by Facebook Comments