WebComponents sind ein Zusammenspiel verschiedener Technologien. Für die Entwicklung ist Erfahrung mit Javascript, HTML und generellen Web-Technologien hilfreich. Insbesondere werden Schnittstellen des Browsers wie Custom-Elements verwendet, um mittels ES6-Klassen WebComponents zu registrieren. Hinzukommen HTML-Templates und HTML-Imports, welche ich für die Entwicklung nicht als notwendig erachte, somit nicht in diesem Artikel behandle.
Light Dom
Dient als Gegenstück zum Shadow Dom, gemeint ist der normale DOM
Shadow Dom
Schirmt den Inhalt vom restlichen Dom ab. Nichts kann raus, manches kann rein. Mit manches, ist CSS gemeint, es ist möglich Styling abhängig von außen zu setzten. Hier nachzulesen
Der Shadow Dom kann in zwei Varianten erstellt werden, genannt mode
.
Open-Mode
var a = document.createElement("div")
a.attachShadow({ mode: "open" });
a.shadowRoot
// #shadow-root (open)
Closed-Mode
var a = document.createElement("div")
var shadowRoot = a.attachShadow({ mode: "closed" });
a.shadowRoot
// undefined
shadowRoot
// #shadow-root (closed)
ECMA-Script
Custom Elements werden mit ES6 Class Syntax definiert, in dem sie von HTMLElement
erben. Dieses Thema beschäftigt uns noch bei der Browserkompatibilität
Version | Beschreibung |
---|---|
ES5 (alt) | reicht nicht für die Entwicklung aus, benötigt Polyfills und transpile. |
ES6 (oder neuer) | Minimum ES6, erkennbar an Arrow functions, Template strings, usw. |
Slot
Damit ist der Teil zwischen den Tags gemeint. In einem Slot kann ein Template oder Inhalt an ein Custom-Element weitergereicht werden.
<my-custom-carousel>
<p>This is my slot</p>
</my-custom-carousel>
Innerhalb der WebCompontent wird dieser Inhalt mittels dem Slot-Tag platziert.
<slot></slot>
Es gibt auch die Möglichkeit mehrere Slots zu definieren, dies geschieht mit named Slots.
<my-custom-carousel>
<div slot=”slide-1”></div>
<div slot=”slide-2”></div>
</my-custom-carousel>
Um einen Named-Slot zu platzieren ist folgender Code notwendig.
<slot name=”slide-1”></slot>
Polyfill
In der Webentwicklung ist unter einem Polyfill, ein Ersatzcode für eine Funktionalität, welche die der Browser nicht von selbst unterstützt, gemeint. Um WebComponents in allen Browsern zu unterstützen, sind leider davon einige notwendig.
Die notwendigen Polyfills gibt es hier: https://github.com/webcomponents/
Attributes
Attribute dienen als Schnittstelle zu einem Custom-Element. Innerhalb der WebComponent ist es möglich, sich über eine Veränderung informieren zu lassen (siehe Custom Elements Lifecycle).
<my-custom-carousel intervall="3000">
Properties
Properties werden über Javascript gesetzt. Teilweise wird dieses Verhalten benötigt, wenn die Komponente von anderen Frameworks wie z.B. Angular verwendet werden. (Mehr dazu in meinem anderen Post WebComponents im Detail)
document.querySelector("#test1").intervall = 4000;
Um den HTML-Standart zu erfüllen, ist es notwendig, das Properties auf Attribute reflektiert werden. Hier zu lesen: https://developers.google.com/web/fundamentals/web-components/customelements#reflectattr
Damit ist gemeint: Wird der obige Code ausgeführt, soll sich automatisch der HTML-Code zu diesem ändern.
<my-custom-carousel id="test1" intervall="4000">
Wie Werden Custom Elements Definiert
customElement.define("my-custom-carousel", class CounterElement extends HTMLElement {
// <my-custom-carousel>
customElement.define("div", { is: "my-custom-carousel" }
// <div is="my-custom-carousel">
Custom Elements Lifecycle
constructor
: damit ist das normale Konstruktor verhalten gemeint, natürlich kein besonderes Verhalten der WebComponents, kann dennoch hilfreich sein.
connectedCallback
: jedes Mal wenn dieses Element mit dem DOM verbunden wird
disconnectedCallback
: jedes Mal wenn dieses Element vom DOM entfernt wird
adoptedCallback
: wird ausgelöst sobald das Element auf ein anderes Dokument verschoben wird
attributeChangedCallback(attributeName, oldValue, newValue)
: wenn sich ein Attribut ändert. Welche Attribute überwacht werden sollen, wird mit der folgenden Zeile bestimmt.
static get observedAttributes() { return ["example"]; }
Kommunikation Mit Webcomponents
Attribute, Properties, Funktionen
Um mit WebComponents von außen zu interagieren eigenen sich Attribute, Properties oder Funktionen.
Events
Events können einen Zustand nach außen liefern. Dazu können CustomEvents gefeuert werden, außerhalb kann auf diese gelauscht werden.
dispatchEvent(new CustomEvent("data-changed", { detail: { data: {...} } }));
document.querySelector("id").addEventListener("data-changed", function(e) { console.log(e.detail) });
Styling
Um ein Styling anzuwenden wird ein Style-Tag definiert welcher als Inhalt das CSS enthält. Aufgrund des ShadowDOMs funktioniert das CSS nur innerhalb dieser Komponente (style encapsulation). Einige Browser können dies Verhalten nicht, dieses Verhalten kann mittels ShadyCSS simuliert werden.
Browser Unterstützung
Wie ich schon erwähnt habe, es gibt einige Browser welche so ihre Probleme mit WebComponents haben. Diese unterstützen einige Features nicht komplett oder unterschiedlich als andere. Deswegen habe ich eine kleine Übersicht erstellt. Aufgrund von möglicher Updates, ist es besser die Tabelle selbst nochmal zu verifizieren. Links findet ihr unterhalb der Tabelle.
Browser | ShadowDom | ShadowDom CSS | ECMA-Script | Polyfills-Free |
---|---|---|---|---|
Chrome | ✓ | ✓ | ES6 | ✓ |
Firefox | ✓ | ✖ | ES6 | ✖ |
Edge | ✓ | ✖ | ES6 (ausreichend) | ✖ |
IE11 | ✖ | ✖ | ES5 | ✖ |
Safari | ✓ | ✓ | ES6 | ✖ |
https://caniuse.com/#feat=custom-elementsv1 https://caniuse.com/#search=shadow%20dom https://caniuse.com/#search=es5 https://caniuse.com/#search=es6