Don't like this style? Click here to change it! blue.css
This is a concept which has a very strong chance of altering the future of web development. At first I didn't understand why it was any different than the current methods. Here is the promise of web components:
You can create or choose from a pool of custom tags that make whatever widget you need.
There are 4 technologies that coalesce into web components:
Imagine grabbing whatever component you want from whomever you want. For instance the next tag in this document
is simply <google-map latitude="39.679702" longitude="-75.751483" map-type="satellite" zoom="18" ></google-map>
Because the above features are not widely supported yet (and may never be), we use what's called a polyfill.
That is, a library that covers missing functionality (but checks for support first). In this case that means
adding the library http://polygit.org/components/webcomponentsjs/webcomponents-lite.js
to your HTML.
Here is a working vanilla web component: http://plnkr.co/edit/raDxEwGz0S4OCCgSXsMx?p=preview (I'm using Plunker for this one because I wanted multiple files.)
The secret sauce for custom elements is this:
document.registerElement('ninja-killa', {
prototype: $baseElement
});
That line tells the DOM that tags with name ninja-killa
should use $baseElement
as
their prototype ($baseElement was just a variable name of mine). It was decided that custom tags MUST
CONTAIN A DASH to avoid conflict with normal tags.
See the Pen Custom Components by Andy Novocin (@AndyNovo) on CodePen.
Build a Tag Create a counter
tag which has a method
start
. When start is called the counter
should begin counting upward from 1 once per
second. Display the current count value in the innerHTML. Put 5 counter tags on your page and add an event
listener to each so that a click triggers
start
.
This totally optional feature lets you have your custom element react to interesting moments in time. The four moments you can react to are:
createdCallback
attachedCallback
detachedCallback
attributeChangedCallback
Better Counter Now update your counter so that it has two attributes
is-running
and count
. When the element is created register the click listener which
toggles the is-running
attribute. Have an attributeChangedCallback which starts or stops the timer
when is-running
is toggled from true to false, and updates the innerHTML when the count
is changed. Now create a tag which is already running and starts at count 20 to your page by using
<counter is-running="true" count="20"/>
.
This concept allows you to create new webpages/DOMs inside of your document that live in their own world. For
instance, imagine that you had a CSS rule on your main page for all div
s. Now you want to use
someone else's gmail widget and it is loaded with divs. Your CSS would be applied to their widget. A Shadow DOM
is its own kingdom, with CSS, HTML, and Javascript all its own.
The secret sauce of shadow DOM is to take an element and do something like:
var shadow = $someElement.createShadowRoot();
Now anything you add to shadow
is in a bubble. For instance, look at my ninja-killa
example. Those SHADOW doms have the CSS rule * {color: salmon}
and the normal paragraph is
unaffected. Likewise .ninja { color: orange}
in the main document would have no impact on the
ninjas.
See the Pen Custom Components by Andy Novocin (@AndyNovo) on CodePen.
Shadow Play create a shadow root on an element. Give that shadow DOM a totally different style than the dom as a whole. Make some listeners at both levels and convince yourself that you understand it all.
It's already clear that I hadn't used the template
tag before (it was missing from my notes on
templates). The missing part of the formula is that the template
tag comes with a
content
attribute for cloning. It is typically used with another cloning command
document.importNode($template.content, true)
(the true is for a deep copy).
This feature, like the ES6 module loading, is up in the air while specs shake out. Firefox won't support it until the ES6 module loader is up and running. So for now polyfills will be needed. You'll pretty much only see this feature in the context of web components as of 2016.
The goal is to have a single file component that you can share around with your friends. For instance the ninja component was made like this:
The secret sauce of HTML imports was
<link rel="import" href="other_component.html">
It was also a little bothersome to find a way to grab the template purely from the second file, which was this:
document.currentScript.ownerDocument
OK, build several animal components (I recommend plunker today because of the multi-file aspect). Build a nice looking animal using however many divs you want, but hide it in the shadow DOM of a simple tag. Populate a page of animals. Can you have them wander around?