Skip to content

Web Components

jwberck edited this page Jun 7, 2017 · 1 revision

This page is not revised in a professional format. These are just notes for my reference when on a company computer, ripped directly out of my evernote with no formatting... I hope anyone coming across this gets some use out of them.

General Web Components

  • Web Components consist of 4 main features which can be used separately or all together:
    • Custom Elements - APIs to define new HTML elements
    • Shadow DOM - Encapsulated DOM and styling, with composition
    • HTML Imports - Declarative methods of importing HTML documents into other documents
    • HTML Templates - The
  • Web Components encapsulate HTML, CSS, but not JavaScript
    • Use a Immediately Invoked Function Expression for this
      • createdCallback function serves this purpose.
  • Uses in the underlying architecture of Angular 2 https://www.webcomponents.org/introduction

Official Dom and shadow DOM documentation https://dom.spec.whatwg.org/#shadow-trees https://w3c.github.io/webcomponents/spec/shadow/

Official Custom Element Documentation https://html.spec.whatwg.org/multipage/scripting.html#custom-elements

Differences between Shadow Dom v0 and v1 ( and other stuff ) https://hayato.io/2016/shadowdomv1/

Talks about the different ways people want to go about web components. There seems to be a lot of disagreement. https://hacks.mozilla.org/2015/06/the-state-of-web-components/

Great website for general web topics https://developers.google.com/web/

Custom Elements

Web Components (Specifically Custom Elements and Templates)

Custom Element: a capability for creating your own HTML elements. Can have their own scripted behavior and CSS styling. Part of Web Components but can also be used by themselves.

  • Requirements
    • name must contain a dash
    • prototype must extend HTMLElement
  • Allows us to bundle markup and styles into custom html elements.
    • fully encapsulate all their html and css
  • Allows lifecycle reactions
    • connectedCallback - Called when the element is inserted into the DOM
    • disconnectedCallback - Called when the element is removed from the DOM
    • attributeChangedCallback - Called when an attribute of the element is added, removed, updated, or replaced
  • Creating a custom element with “Upgrade” method ( old syntax )
    • 1) Create prototype extending HTML Element
    • var containerProto = Object.create(HTMLElement.prototype);
    • 2) Create createCallback method in document object
      • When the browsers parser finds a custom html tag it will immediately check its createCallback function. If found, it will run immediately.
      • This is good for setting up the custom element.
      • Can use it to create shadow Dom and clone template into it.
      • containerProto.createdCallback = function() {
                // create shadow host on "this", the root var is known as the shadow root.
                var root = this.createShadowRoot();
                // attatch the template to the shadow root
                root.appendChild(document.importNode(template.content, true));
              }
    • We pass the tag name and prototype to a new method on the document, called registerElement, and after that we're ready to go.
    • var shadowContainer = document.registerElement('custom-container', {
              prototype: containerProto
            })

    // Creation methods:
          // 1) HTML tag <custom-container></custom-container>
          // 2) use shadowContainer var
          // 3) use document.createElement("custom-container")

  • Creating a custom element with synchronous constructor method
  • class SaveBtn extends HTMLElement {    // You can extend any other element or Class

       constructor() {                  
          super();                         //  construct the original item to be extended, here it is the HTMLElement
       }
      
    // Define the required of the 4 available callbacks
    // Define getters and setters
     
    }

  • Use getters and setters to define properties
    • Set properties in html by using the “data-“ assignment
    • <!-— Set a parameter “text” for the element load-button by using “data-“ assignment —>
      <load-buttondata-text='click this'></load-button>
    • Set properties with javascript with “.” notation
    • myLoadBtn.text = ‘click this’;
      // OR
      // if the element has a property setter like set properties(prop){} use this method
      myLoadBtn.properties= {text: ‘click me’};
  • Create and Declare elements
    • Enable by using the Document.registerElement() method
    • var MyLoadBtn = document.registerElement(“load-button”, LoadBtn);
    • Declare the element
      • Use HTML 
        • <load-button></load-button>
      • Use JavaScript
      • var myBtn = new MyLoadBtn;
        document.querySelector('#placeholder').appendChild(myBtn);
  • Style and Adding Markup
    • Style within the connectedCallback()
  • V1 Standard Concepts
    • customElements global ( replaces document.registerElement )
      • the customElements global is used to define a custom element
      • call customElements.define() with the tag name you want to create and a class that represents that element
      • classAppDrawerextendsHTMLElement{...}
        window.customElements.define('app-drawer', AppDrawer);

        // Or use an anonymous class if you don't want a named constructor in current scope.
        window.customElements.define('app-drawer', class extends HTMLElement {...});




# Shadow DOM
Allows the web browser to render DOM elements without putting them into the main document DOM tree.
  • Why?
    • Allows for separation of concern from browser and developer.
    • Dev can’t access the Shadow DOM in the same way they would access nested elements
    • Browser can render and modify that code in the same way it would any other elements.
    • Allows for encapsulation of CSS styling, preventing external styling from leaking into the object
    • Can still fire events that can be picked up by other elements in the doc.
  • Shadow Tree
    • Scoped subtree in an element
    • Element that it is attached to is called a shadow Host
  • Shadow Host
    • Call createShadowRoot on an element in the DOM to attach a ShadowHost to it.
    • This is the only piece visible to the user, how they interact with it.
    • Kind of like a method signature, its where they would put their parameters.
  • Shadow Root
    • document fragment returned by createShadowRoot
    • ShadowRoot and its children are hidden from the user, but the browser uses it like normal html/css
  • Shadow Boundary
    • The thing that actually encapsulates the shadow DOM
    • prevents css from bleeding into shadow DOM
    • prevents javascript from going into shadow root
  • Must always be connected to existing elements in the DOM either through scripting or manual attachment
    • Attach shadow dom to element with element.attachShadow({mode : ‘open’}) or element.attachShadow({mode : ‘closed’})
  • Essential for creating custom elements.
    • Without shadow DOM, different custom elements could interact in unwanted ways.
  • Two modes for shadow DOM
    • Open: You can access the Shadow DOM with the shadowRoot property of the HTMLElement (this was the default in v0)
    • Closed: You can’t access the Shadow Dom with the shadowRoot property, it returns null instead ( the video tag is an example of closed mode. javascript can’t access it)
  • Certain elements can’t host a shadow tree
    • If that element already has its own internal shadow dom (input or texture)
    • if it doesn’t make sense for that element to host a shadow dom ( img )


Example of importing template into shadow dom

<template>
  <!-- Full of slider awesomeness -->
</template>

<div class="img-slider"></div>

<script>

  // Add the template to the Shadow DOM
  var tmpl = document.querySelector('template');
  var host = document.querySelector('.img-slider');
  var root = host.attachShadow({mode: ‘open’});
  root.appendChild(document.importNode(tmpl.content, true));
</script>


  • Insertion Points
    • Analogous to creating parameters for a function call
    • If you want the images from the image slider to be provide by the user you must use this.
    • Use the <content> tag to pull items into the shadow DOM
    • <content> tag uses CSS selectors to pick elements from the shadow host and project them into the shadow DOM
      • The projection itself is technically known as the Insertion Point

Template for this functionality
<template>
     …
     <div class="inner”>
     <content select="img”>
    </content>
    </div>
</template>

Also need to use  ”content" pseudo-element to update CSS

#slides ::content img {
width: 25%;
float: left;
}


Template



Templates are the blueprints for web components. 
  • It allows you to store markup and reuses it later. (so like object oriented html?)
  • Everything inside a template is considered inert by browsers.
    • This means that nothing in the template is rendered until we activate it with javascript

<template>
    <h1>Hello there!</h1> 
    <p>This content is top secret :)</p>
</template>

Clone this wiki locally