One of the major challenges of building rich applications for the web, is that our foundation (JavaScript in the browser) is a document viewer, not an application platform. In fact, if you show a mobile or desktop app developer the primitives that we web developers are given to start with, the typical reaction is that we’re missing many important building blocks.
All of the tools we rely on like Angular 2, React, Ember, Polymer, etc... are, essentially, shims and hacks that we make use of while we wait for things like the W3C Web Component spec to be completed and implemented in browsers. As it becomes more feasible to build on the standards instead of a framework, it'll become useful for developers to have awareness of what those standards are, what’s missing from the official spec, and how well of a job our favorite libraries do with establishing alignment.
We’ll take a close look at the W3C component spec, and compare it to the concept of a Component in the React.js library, the and the Ember.js 2 and Angular 2 frameworks. We’ll try to do a few things using native web components, involving rendering and styling an encapsulated piece of interactive UI. Along the way, we will highlight the things that we’re waiting in the W3C spec. We'll be left with a clear roadmap of when we can start decoupling our apps from a specific third party tool and rely on “Native Web Components” in production.
2. INTRODUCTION
WHO’S THIS GUY?
▸ CTO Levanto Financial
▸ frontendmasters.com instructor
▸ Product Guy
▸ I do a lot of JavaScript OSS stuff
▸ I work with Ember & React a lot
7. INTRO
THE W3C WEB COMPONENT SPEC
HTML IMPORTS
HTML TEMPLATES
CUSTOM ELEMENTS
SHADOW DOM
8. INTRO
THE W3C WEB COMPONENT SPEC
HTML IMPORTS
▸ require() for HTML
▸ onload, onerror events
▸ can bring in css/html/js
▸ closure-like js characteristics
9. INTRO
THE W3C WEB COMPONENT SPEC
CUSTOM ELEMENTS
▸ Custom HTML vocab
▸ Life-cycle
▸ Extensibility
▸ Interoperability (we hope?)
10. INTRO
THE W3C WEB COMPONENT SPEC
HTML TEMPLATES
▸ Inert HTML in the DOM
▸ Defer loading / rendering
▸ Think: handlebars/jade/etc…
11. INTRO
THE W3C WEB COMPONENT SPEC
SHADOW DOM
▸ CSS Encapsulation
▸ DOM encapsulation
▸ Each component has own
subtree w/in parent page
12. INTRO
THE W3C WEB COMPONENT SPEC
HTML IMPORTS
HTML TEMPLATES
CUSTOM ELEMENTS
SHADOW DOM
16. <template id="something">
<!-- Some style -->
<style type="text/css">
.title {
font-size: 24px;
}
</style>
<!-- Some behavior -->
<script type="text/javascript">
</script>
<!-- Some structure and content -->
<div class="frame">
<h3 class="title">I am a title</h3>
<p class="body">I am the body</p>
</div>
</template>
17. // Grab the template
var tmpl = document.querySelector(‘#something');
Add the cloned document fragment to the DOM
document.body.appendChild(
// Clone the template's document fragment
document.importNode(tmpl.content, true)
);
18. // Grab the template
var tmpl = document.querySelector(‘#something');
Add the cloned document fragment to the DOM
document.body.appendChild(
// Clone the template's document fragment
document.importNode(tmpl.content, true)
);
37. <link rel="import" href="myfile.html" />
// Get document fragment of an import
var content = document
.querySelector('link[rel="import"]')
.import;
// From a <script> included with the import,
// access imported DOM
var $abc = document
.currentScript
.ownerDocument
.querySelector('.abc');
43. CUSTOM ELEMENTS
REGISTERING
// Extend a DOM element prototype
var MegaButtonProto =
Object.create(HTMLButtonElement.prototype);
// Register your new element type
var MegaButton =
document.registerElement("mega-button", {
prototype: MegaButtonProto,
extends: "button"
});
44. CUSTOM ELEMENTS
ADDING A TEMPLATE
// Template
var infoBoxTemplate = document.querySelector('#info-pane-template');
// Extend a DOM element
var InfoBoxProto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
// Create the shadow root
this.createShadowRoot().appendChild(
// Add the template to the shadow root
document.importNode(infoBoxTemplate.content, true)
);
}
}
});
45. CUSTOM ELEMENTS
ADDING A TEMPLATE
// Template
var infoBoxTemplate = document.querySelector('#info-pane-template');
// Extend a DOM element
var InfoBoxProto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
// Create the shadow root
this.createShadowRoot().appendChild(
// Add the template to the shadow root
document.importNode(infoBoxTemplate.content, true)
);
}
}
});
46. // Template
var infoBoxTemplate = document.querySelector('#info-pane-template');
// Extend a DOM element
var InfoBoxProto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
// Create the shadow root
this.createShadowRoot().appendChild(
// Add the template to the shadow root
document.importNode(infoBoxTemplate.content, true)
);
}
}
});
CUSTOM ELEMENTS
ADDING A TEMPLATE