Web Components Community πŸ”·

Cover image for Web-Components #102 - 5 more lessons after learning Web Components #101
Danny Engelman
Danny Engelman

Posted on

Web-Components #102 - 5 more lessons after learning Web Components #101

Standing on the shoulders of giants

I learned as much as I could on Web Components development over the past 5 years. And I am still learning.

Credit where credit is due!

I could not have gotten this far without the answers on StackOverflow, the discussions on GitHub and the blogs from early-adoptersΒΉ.

ΒΉ) Old blogs can refer to V0 Web Component technologies not available in the current V1 standard


5 lessons to make your Web Component code better

  • Most (early) examples showed all three Web Component technologies in one code example

    • templates
    • shadowDOM
    • custom Elements API

Each can be used without the other:

  • πŸ“ You can use templates for any block of inert HTML

  • πŸ“ You can assign shadowDOM to regular HTML Elements

  • πŸ“ You can create Custom Elements without templates or shadowDOM


πŸ¦„ 1. <template>

  • creates inert HTML snippets, where previously you would have used:
  <script type="application/html">...</script>
    or
  <div style="display:none">...</div>
Enter fullscreen mode Exit fullscreen mode
  • Templates are parsed when you use template.content.cloneNode(true)

  • If you use template content once, you can skip the .cloneNode(true) part

  • Do not use a <template> just because most (early) blogs show:

  let template = document.createElement("template");
  template.innerHTML = ` CSS & HTML CONTENT `;
  this.shadowRoot.innerHTML = template.innerHTML;
Enter fullscreen mode Exit fullscreen mode

This is a very expensive way of writing:

  this.shadowRoot.innerHTML = ` CSS & HTML CONTENT `;
Enter fullscreen mode Exit fullscreen mode
  • My personal preference, when I do use/need Templates, is to keep <template>s in the <head> of the document.

    • They load early
    • My IDE does all syntax highlighting
    • I use id="UPPERCASE" so they stand out, and the <my-element> can have a generic statement: document.getElementById(this.nodeName) to read the <template>
    
      <template id="MY-ELEMENT">
        <style>
          :host { ... }
        </style>
        <div><slot><slot></div>
      </template>
    
    

    Use this.localeName for id="lowercase"


πŸ¦„ 2. super()

  • super() sets and returns the this scope.
  constructor() {
    super();
    this.title = "Web Components 102";
  }
Enter fullscreen mode Exit fullscreen mode

can be written as:

  constructor() {
    super().title = "Web Components 102";
  }
Enter fullscreen mode Exit fullscreen mode

πŸ¦„ 3. always call super() first in constructor

  constructor() {
    // Always call super first in constructor
    super();
    // Element functionality written in here
  }
Enter fullscreen mode Exit fullscreen mode

What they meant to say was:

  constructor() {
    // You can *not* reference 'this' *before* it is created by super();
    // It is valid to use *any other* JavaScript *before* super()
    const template = () => document.getElementById(this.nodeName).content.cloneNode(true);
    super().append( template() );
  }
Enter fullscreen mode Exit fullscreen mode

‼️ Note: template() is a function, it is called after super() created the 'this' scope. So this.nodeName works


πŸ¦„ 4. attachShadow

  • attachShadow sets and returns this.shadowRoot

So there is no need to create your own property:

    let shadow = this.attachShadow({mode:"open"});
Enter fullscreen mode Exit fullscreen mode
  constructor(){
      super();
      let shadow = this.attachShadow({mode:"open"});
      shadow.innerHTML = `...`;
  }
Enter fullscreen mode Exit fullscreen mode

can all be chained:

  constructor(){
      super() // sets AND returns 'this'
        .attachShadow({mode:"open"}) // sets AND returns this.shadowRoot
        .innerHTML = `...`;
  }
Enter fullscreen mode Exit fullscreen mode

πŸ¦„ 5. appendChild vs. append

  • IE11 did not have the el.append(nodes) method; maybe that is why so many developers stick to appendChild

  • el.appendChild(element) - MDN appendChild documentation

    appends one element, and returns the element reference

  • el.append(nodes) - MDN append documentation

    appends all nodes (text nodes & elements), and returns nothing

    append does not parse HTML, like .innerHTML and .insertAdjacentHTML do

  • When you do not need the appendChild return value; you can rewrite:

    
      const shadow = this.attachShadow({mode: 'open'});
      const div = document.createElement('div');
      const style = document.createElement('style');
      shadow.appendChild(style);
      shadow.appendChild(div);
    

    to:

    
      this.attachShadow({mode: 'open'})
          .append( 
                  document.createElement('div')  ,
                  document.createElement('style')
                 );
    



Top comments (1)

Collapse
sjain profile image
surbhi nahta • Edited on

JAVA is an exceptional totally steady programming language. It is the speediest making and secure programming language. Seen by Oracle, this language is used on 3 billion contraptions from one side of the world to the other, meaning java will happen for eternity. JAVA is used to make web applications, games, more modest applications, business protests, etc. There is a wide level of JAVA as it will in regular be used in the advancement of an endeavor.
Job Oriented Java Certification Course in Pune