background

If you’ve ever developed an applet you’ve probably seen something like this

This is what it looked like when I first saw it

What is this? The iframe? What happened to my packaged component? In fact, this is generated by Exparser, the component organization framework of wechat small program, but today’s protagonist is not it, but its biological father webComponent, both of which have highly similar content. Exparser, or Exparser, is a set of custom elements implemented by the webComponent standard to better meet the needs of small program development.

We’ve all used the Video TAB. Have you ever wondered why passing in a link can generate a video with pause, play, etc.? Where did all those elements go? There’s also the pr or issue content box on Github. If you notice the element, it’s a Textarea tag, but nothing I type is visible.

In fact, we can make these hidden contents explicit by checking debugger => Settings => Preferences => Shadow DOM of explicit user agent. This is the magic webComponent.

WebComponent

create

To distinguish webComponents from HTML tags, they must be used as barbecue skewers

<body>
  <hello-world></hello-world>
</body>
Copy the code

The Hello-world component can define content in two ways

Js script format

  <body>
    <hello-world></hello-world>
  </body>
  <script>
    // All custom components inherit from HTMLElement
    class HelloWorld extends HTMLElement {
      constructor() {
        super(a);// This is also a must
        
        // The specific functions of the element are described below
        
        // Mode has two modes, open and closed, which allow external access to the interior of a custom element
        var shadow = this.attachShadow( { mode: 'open'})var container = document.createElement('div')
        container.innerText = 'hello world'
        shadow.appendChild(container)
      }
    }
    
    // Tell the browser that the 
       
         element is associated with this class
       
    window.customElements.define('hello-world', HelloWorld); 
  </script>
Copy the code

The template form

<body>
  <hello-world></hello-world>
  <! -- Use template to define the component's HTML, style, js -->
  <template id="helloworldTemplate"> 
    <! Styles should be wrapped inside components
    <style>
     :host { /** :host defines the current custom element style **/
       border: 1px solid red;
       height: 100px;
       display: flex;
       flex-direction: column;
       align-items: center;
       justify-content: center;
     }
     .conatiner {
       color: red;
     }
    </style>
  
    <div class="container">hello world</div>
  </template>
  <script>
    class HelloWorld extends HTMLElement {
      constructor() {
        super(a)// The script content is basically the same as above, except that dom creation is no longer required
        var shadow = this.attachShadow( { mode: 'closed'})var templateElem = document.getElementById('helloworldTemplate')
        
        // The contents of the template can only be retrieved by calling templateem.content
        var content = templateElem.content.cloneNode(true)
        shadow.appendChild(content)
      }
    }
    window.customElements.define('hello-world', HelloWorld);   
  </script>
</body>
Copy the code

Simply passing a template creates a template in the DOM tree that is no longer displayed on the page. As shown below.

Add event

A component needs interaction in addition to styling, which we can do by listening for events inside the component

    class HelloWorld extends HTMLElement {
      constructor() {
        super(a);var shadow = this.attachShadow( { mode: 'open'});var templateElem = document.getElementById('helloworldTemplate');
        var content = templateElem.content.cloneNode(true);
        
        // Get the node
        const dom = content.querySelector('.container')
        // Add events
        dom.addEventListener('click'.() = > {
          alert('hello world') }) shadow.appendChild(content); }}window.customElements.define('hello-world', HelloWorld);    
  </script>
Copy the code

Encapsulate components in pure JS form

// demo.js
// Define a template first
let template = document.createElement("template")
template.setAttribute('id'.'helloWorldTemplate')

// Insert the contents of template
template.innerHTML = `  
      
hello world
`
document.body.append(template) // This is the same as writing template manually // Here is the js script class HelloWorld extends HTMLElement { constructor() { super(a);var shadow = this.attachShadow( { mode: 'open'});var templateElem = document.getElementById('helloWorldTemplate'); var content = templateElem.content.cloneNode(true); const dom = content.querySelector('.container') dom.addEventListener('click'.() = > { alert('hello world') }) shadow.appendChild(content); }}window.customElements.define('hello-world', HelloWorld); Copy the code

Finally, reference the script in the page to automatically create the custom component

<body>
  <hello-world></hello-world>
  <script src="./demo.js"></script>
</body>
Copy the code

reference

Ruan Yifeng Web Components example tutorial

# MDN use shadow DOM

# MDN Web Components