What the hell are Web Components?
Tech Lead & Open-Source Champion at Softwire
Web Components
Web Components
Web Components
<nav-bar>
<ul>
<li><a href="/1">Home</a></li>
<li><a href="/2">Link</a></li>
<li><a href="/3">Link</a></li>
</ul>
</nav-bar>
Web Components
- <Template>
- HTML Imports
- Shadow DOM
- Custom Elements
Current Templates
<div id="img-with-caption-template" style="display: none">
<img src="/default-image.png" />
<h3 class="title">Super cool image!</h3>
</div>
Current Templates (Knockout)
<script type="text/html" id="img-with-caption">
<img src="/default-image.png" />
<h3 class="title">Super cool image</h3>
</script>
<Template>
<template id="img-with-caption">
<img src="/default-image.png" />
<h3 class="title">Super cool image</h3>
</template>
<Template>
<template id="img-with-caption">
<img src="/default-image.png" />
<h3 class="title">Super cool image</h3>
</template>
<script type="text/javascript">
var template = document.querySelector("#img-with-caption");
var content = document.importNode(template.content, true);
document.body.appendNode(content);
</script>
HTML Imports
<head>
<link rel="import" href="otherFile.html" />
</head>
HTML Imports
index.html
<head>
<link rel="import"
href="import.html" />
</head>
import.html
Some HTML!
<style>
h1 { font-size: 500%; }
</style>
<script>
window.aThing = function () {
...
}
</script>
Shadow DOM
Shadow DOM
Some boring content
<div id="myDiv">Some boring content<div>
<script type="text/javascript">
var div = document.querySelector("#myDiv")
var shadow = div.createShadowRoot();
shadow.innerHTML = '<h3>Dom-invisible headline!</h3>';
</script>
Shadow DOM
Real content
<div id="myDiv2">
Real content
</div>
<script type="text/javascript">
var div = document.querySelector("#myDiv2")
var shadow = div.createShadowRoot();
shadow.innerHTML =
"<h3>" +
"Originally: <content></content>" +
"</h3>";
</script>
Custom Elements
document.registerElement('nav-bar');
<nav-bar>
<ul>
<li>Home</li>
<li>Link</li>
<li>Link</li>
</ul>
</nav-bar>
Custom Elements
var NavBarPrototype = Object.create(HTMLElement.prototype);
NavBarPrototype.doThings = function () { ... }
document.registerElement('nav-bar', {
prototype: NavBarPrototype
});
...
document.querySelector("nav-bar#my-menu").doThings();
Custom Elements
var NavBarPrototype = Object.create(HTMLElement.prototype);
NavBarPrototype.createdCallback = function () { ... }
NavBarPrototype.attachedCallback = function () { ... }
NavBarPrototype.detachedCallback = function () { ... }
NavBarPrototype.attributeChangedCallback = function () { ... }
document.registerElement('nav-bar', {
prototype: NavBarPrototype
});
Custom Elements
var NavBarPrototype = Object.create(HTMLElement.prototype);
NavBarPrototype.createdCallback = function () {
this.innerHTML = '<div class="bs-example bs-navbar-top-example"> \
<nav class="navbar navbar-default navbar inverse"> \
...';
};
document.registerElement('nav-bar', {
prototype: NavBarPrototype
});
<template id="navBarTemplate">
<div class="bs-example bs-navbar-top-example">
<nav class="navbar navbar-default navbar inverse">
...
<content></content>
...
</nav>
</div>
</template>
<script>
var NavBarPrototype = Object.create(HTMLElement.prototype);
NavBarPrototype.createdCallback = function () {
var template = document.querySelector("#navBarTemplate");
var content = document.importNode(template.content, true);
this.createShadowRoot().appendNode(content);
};
document.registerElement('nav-bar', {
prototype: NavBarPrototype
});
</script>
Let's put it together
Actually using this?
Specced | Implementation | |||||
---|---|---|---|---|---|---|
Polyfill | Chrome / Opera | Firefox | Safari | IE | ||
Templates | Stable | Stable | 8 | |||
HTML Imports | Stable | Behind flag | ||||
Custom Elements | Stable | Behind flag | ||||
Shadow DOM | Stable | Behind flag |
(From Are We Componentized Yet?)
Frameworks
- Knockout
- Ember
- Angular (in 2.0)
Web components!
Tech Lead & Open-Source Champion at Softwire