modern web ui - web components
Post on 14-Jul-2015
875 Views
Preview:
TRANSCRIPT
TOMORROW’S COMPONENTS, TODAY!
<presentation>
THE WEB WAS BUILT FOR…Document
Viewer
Document
2006 2007 2008 2009 2010 2011 2012 2013 201420052004
ES3 ES4 ES5 ES2015
1999
6 7 8 9 11
WHERE WE’VE BEEN
THE BROWSER AS AN APPLICATION PLATFORM
• Powerful new language standards (TC39)
• Uniting around web standards (W3C)
• Use tomorrow’s technology today (Babel, Web Frameworks)
HOW COMPONENTS HELP• Encapsulation
• Maintainability
• Testability
• Scalability
• Extensibility
HTML5 WEB COMPONENTS
• HTML Templates
• Shadow DOM
• Custom Elements
• HTML Imports
HTML TEMPLATESWhat’s the point?
• Get some HTML into the DOM, and have it remain inert
• Defer loading of resources
• Defer rendering of content
HTML TEMPLATES
<script type=“text/x-handlebars-template" id="something">
<div class="frame"><h3 class="title">{{title}}</h3><p class="body">{{body}}</p>
</div></script>
Handlebars
HTML TEMPLATES
<template id="something"><div class="frame">
<h3 class="title">I am a title</h3><p class="body">I am the body</p>
</div></template>
Native
HTML TEMPLATES<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>
HTML TEMPLATESAdd to the DOM
Example: http://codepen.io/TrueNorth/pen/xbyVgL?editors=101
// Grab the templatevar tmpl = document.querySelector('#something');// Add the cloned document fragment to the DOMdocument.body.appendChild(
// Clone the template's document fragmentdocument.importNode(tmpl.content, true)
);
SHADOW DOMWhat’s the point?
• CSS rules bleeding into UI components is annoying
• DOM encapsulation is poor, unless you iframe
• Shadow DOM is a subtree within the parent page
SHADOW DOM
• Shadow Root - root element of DOM subtree
• Shadow Host - parent of a shadow root
Application DOM
Component
Shadow DOM
SHADOW DOMCreating a Shadow Root
// Grab an elementvar elem = document.querySelector("#good-host");// Create the shadow rootvar root = elem.createShadowRoot();// Create a new elementvar h1 = document.createElement("h1");h1.innerHTML = "Hello World";// Append to the shadow rootroot.appendChild(h1);
SHADOW DOMAdd a template to the mix
Example: http://codepen.io/TrueNorth/pen/OPBNmq?editors=101
<template id="something"> <h1>Hello, world!</h1> <p>This is part of my component</p></template>
<div id="good-host"></div>
// Grab an elementvar elem = document.querySelector("#good-host");// Create the shadow rootvar root = elem.createShadowRoot();
// Grab the templatevar tmpl = document.querySelector('#something');// Add the cloned document fragment to the DOMroot.appendChild(
// Clone the template's document fragmentdocument.importNode(tmpl.content, true)
);
SHADOW DOMStyling
• Style defined/loaded within the shadow DOM only applies to shadow DOM
• :host pseudo-selector - for outer element
:host {border: 1px solid red;
}
:host(.hover) {border: 1px solid blue;
}
SHADOW DOMStyling
• The ::shadow pseudo-selector penetrates a shadow root
• the /deep/ pseudo-selector penetrates all shadow roots
SHADOW DOMStyling
.example-host { border: 1px solid purple; padding: 10px; margin: 10px;}#good-host p { color: blue;}#better-host::shadow p { color: red;}#better-host/deep/ h1 { color: cyan;}
<template id="something"> <h1>Hello, world!</h1> <p>This is part of my component</p> <content></content></template>
<div id="good-host" class="example-host"></div><div id="better-host" class="example-host"> <div id="best-host" class="example-host"></div></div>
Example: http://codepen.io/TrueNorth/pen/MYPyOe
SHADOW DOMContent Projection
• <content> tag to project all content
• <content select=“”> to project selected content
<template id="something"> <h1><content select=".h1"></content></h1> <p>This is part of my component</p> <content></content></template>
Examples: http://codepen.io/TrueNorth/pen/emPZMv
CUSTOM ELEMENTSWhat’s the point?
• Compose larger parts of an app declaratively
• Provide a standard and consistent life-cycle
• Extensibility
CUSTOM ELEMENTSRegistering
// Extend a DOM element prototypevar MegaButtonProto = Object.create(HTMLButtonElement.prototype);
// Register your new element typevar MegaButton = document.registerElement("mega-button", { prototype: MegaButtonProto, extends: "button"});
CUSTOM ELEMENTSAdding templates
// Templatevar infoBoxTemplate = document.querySelector('#info-pane-template');
// Register the custom elementvar InfoBox = document.registerElement("info-pane", {
prototype: Object.create(HTMLElement.prototype, {createdCallback: {
value: function () {// Create the shadow rootthis.createShadowRoot()// Add the template to the shadow root.appendChild(
document.importNode(infoBoxTemplate.content, true)
);}
}})
});
Examples: http://codepen.io/TrueNorth/pen/gbBmMR
HTML IMPORTS• #include for the web
• onload, onerror hooks
• Can include CSS, JS and HTML
• Content can be accessed from the outside
• HTML Imported JS can reference either the main DOM or imported document fragment
<link rel="import"href="myfile.html" />
// Get document fragment of an importvar content = document
.querySelector('link[rel="import"]')
.import;
// From a <script> included,// with the import access,// imported DOMdocument
.currentScript
.ownerDocument
.querySelector('.abc');
A REAL USE CASE• Declarative Syntax
• Responds to click
<hamburger-menu title="My Menu"> <hb-menu-item href="#abc" caption="Better get on these soon"> Serious Bugs </hb-menu-item> <hb-menu-item href="#def" caption="Oh %#@$!"> Really Serious Bugs </hb-menu-item></hamburger-menu>
Starting Point: http://codepen.io/TrueNorth/pen/PwdLrjComponentized: http://codepen.io/TrueNorth/pen/xbyqMEHTML Importified: http://codepen.io/TrueNorth/pen/ogawLm
• Content projection
• Style on shadow root
</presentation>
<questions> ? </questions>
top related