Pseudorandom Knowledge

Web components of HTML

Web Components consists of four separate standards. Together they aim to facilitate the creation of reusable and self-contained pieces of HTML (with JavaScript and CSS). Browser support is lacking but can be polyfilled.

Templates

The template tag holds markup that can be used from JavaScript. It provides a browser native alternative to JavaScript templating libraries.

<div class="fact">All birds are animals</div>
<div class="fact">Some animals are dogs</div>
 
<template id="fact-box">
    <h1>Fact</h1>
    <p></p>
</template>
 
<script>
    var template = document.querySelector("#fact-box").content;
    var facts = document.querySelectorAll(".fact");
    [].forEach.call(facts, function(fact) {
        var clone = document.importNode(template, true);
        clone.querySelector("p").innerHTML = fact.innerHTML;
        fact.replaceChild(clone, fact.firstChild);
    });
</script>

Shadow DOM

The shadow DOM is a way to create nested DOMs. They can then be styled independently from the rest of the page. The content tag provides a way to enter content into the shadow DOM from the shadow root element.

<div class="fact">All birds are animals</div>
<div class="fact">Some animals are dogs</div>
 
<template id="fact-box">
    <h1>Fact</h1>
    <p><content></content></p>
</template>
 
<script>
    var template = document.querySelector("#fact-box").content;
    var facts = document.querySelectorAll(".fact");
    [].forEach.call(facts, function(fact) {
        var clone = document.importNode(template, true);
        fact.createShadowRoot().appendChild(clone);
    });
</script>

Custom elements

Creating custom elements allow us to name our pieces of HTML. To distinguish user made tags from official tags the former must always contain a hyphen.

<fact-box>All birds are animals</fact-box>
<fact-box>Some animals are dogs</fact-box>
 
<template id="fact-box">
    <h1>Fact</h1>
    <p><content></content></p>
</template>
 
<script>
    var template = document.querySelector("#fact-box").content;
    var prototype = Object.create(HTMLElement.prototype);
    prototype.createdCallback = function() {
        var clone = document.importNode(template, true);
        this.createShadowRoot().appendChild(clone);
    };
    document.registerElement("fact-box", {prototype: prototype});
</script>

HTML imports

Finally, with HTML imports, the finished web component can be placed in an HTML file and imported where it is needed.

<head>
    <link rel="import" href="fact-box.html">
</head>
 
<fact-box>All birds are animals</fact-box>
<fact-box>Some animals are dogs</fact-box>
fact-box.html
<template id="fact-box">
    <h1>Fact</h1>
    <p><content></content></p>
</template>
 
<script>
    var thisDocument = document.currentScript.ownerDocument;
    var template = thisDocument.querySelector("#fact-box").content;
    var prototype = Object.create(HTMLElement.prototype);
    prototype.createdCallback = function() {
        var clone = document.importNode(template, true);
        this.createShadowRoot().appendChild(clone);
    };
    document.registerElement("fact-box", {prototype: prototype});
</script>