Manchmal setzen wir web-components ein. Eine Technologie um, unabhängig von großen Frameworks wie React oder Vue, kleine Komponenten für Webseiten zu bauen. Hier eine kurze Einführung:
Web-Components sind eine Sammlung aus vier Standards:
Kurz gesagt, setzt eine Web Komponente diese 4 Werkzeuge sinnvoll ein, um wiederverwendbare Bausteine für Webseiten zu bauen.
Der Schlüssel zu einer neuen Web Komponente ist das Attribut
window.customElements
. Mit ihm kann man eine neue Komponente definieren. Dazu schreibt man eine Klasse, z.B. DropDown
, wir zeigen gleich wie, und registriert sie als Web Komponente:
window.customElements.define('drop-down', DropDown)
Der erste Parameter ist natürlich der Name des Tag. Er muss einen Bindestrich enthalten.
Die Klasse für die Komponente sieht nicht allzu kompliziert aus.
Sie wird von HTMLElement
abgeleitet:
class DropDown extends HTMLElement {
constructor() {
super();
}
Wir geben Ihr noch ein Attribut - damit kann sie dann z.B. so genutzt werden:
<drop-down name="test" />
:
set name(option) {
this.setAttribute("name", option);
}
get name() {
return this.hasAttribute("name");
}
Wenn die Komponente in die Seite eingefügt wird, wird dieser Callback aufgerufen. Er fügt dem DOM zunächst ein Shadow-DOM hinzu und befüllt diesen dann. Dazu wird ganz einfach ein interpolierter JavaScript-String eingesetzt.
connectedCallback() {
let shadowDom = this.attachShadow({ mode: "open" })
shadowDom.innerHTML = `
<select name="${this.name}>
<option>1</option>
<option>2</option>
</select>
`;
}
}
… fertig!
Das mit dem JavaScript String ist so eine Sache… Natürlich mischt man damit Code und Darstellung. Eine Alternative wäre die Nutzung von HTML-Templaten, die in die HTML-Seite eingebettet und in der Komponente referenziert werden. Aber das zerstört natürlich die Kapselung: Das Templat soll ja Teil der Komponente und nicht der Seite sein.
Das Beste ist also, die Komponente nicht in einer JavaScript-Datei, sondern in einer HTML-Datei unterzubringen, die so aussieht:
<template id="my-drop-down">
<select name="${this.name}>
<option>1</option>
<option>2</option>
</select>
</template>
<script>
class DropDown extends HTMLElement {
....
}
window.customElements.define('drop-down', DropDown)
</script>
Der Callback muss dann nur folgendermaßen umgeschrieben werden:
connectedCallback() {
let shadowDom = this.attachShadow({ mode: "open" });
let template = document.getElementById("my-drop-down");
let templateHtml = template.content.cloneNode(true);
shadowDom.appendChild(templateHtml);
let select = shadowDom.getElementByTagName('select')[0]
select.setAttribute('name', this.name())
}
Naja… das ist ja der Zweck…
Aber keine Angst, auf webcomponents.org gibt es massenhaft fertige Komponenten, einfach mal reinschauen!
Und dann gibt es noch Polymer, dessen Projekt lit-element den Umgang mit Web Komponenten etwas einfacher gestaltet.