DEV Community

Discussion on: Webcomponents: It's really that easy!

Collapse
 
justinfagnani profile image
Justin Fagnani

What is the purpose of using a <template> in your example? You never clone it, you're just getting it's innerHTML as a string. This makes it a very expensive string holder.

You could simplify what you have to roughly this without the template:

export class AllCaps extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({mode: 'open'});
        let toUpper = this.firstChild.nodeValue.toUpperCase();
        this.shadowRoot.innerHTML = `
          ${toUpper}
          <slot></slot>
          ${this.getAttribute('addition')}
          <style>
            :host{
             color: red;
            }
          </style>
        `;
    }
}
Enter fullscreen mode Exit fullscreen mode

But not that with both a <slot> and copying the text content, you'll be displaying the content twice. You're also reading the attribute in the constructor, but it may not be set there yet.

Collapse
 
sroehrl profile image
neoan

Yes, you are absolutely right. As mentioned in several disclaimers throughout this post, this is not the structure you would go for. This example element is meant to introduce several concepts and by no means represents an actual custom element.
I carefully chose this setup to accommodate for progression throughout this tutorial and made some crude decisions to maintain overview yet somewhat of a separation.
As I am also concerned about potential readers imitating such a pattern: do you think I haven't mentioned used anti-patterns enough, or is your feedback only based on the actual code snippets?

Collapse
 
dannyengelman profile image
Danny Engelman • Edited

Or maybe simplify it to:

<all-caps>this is uppercase</all-caps>
<script>
  customElements.define("all-caps", class extends HTMLElement {
    constructor() {
      const toUpper = x => x.firstChild.nodeValue.toUpperCase();
      const style = "<style>:host{color:red}</style>";
      super()
        .attachShadow({mode: "open"})
        .innerHTML = style + toUpper(this);
    }
  })
</script>
Enter fullscreen mode Exit fullscreen mode

comming back 2 years later

There is a bug in all replies code! There is no DOM available in the constructor when the Web Component is defined before being used in the DOM