aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/web_components
diff options
context:
space:
mode:
Diffstat (limited to 'files/de/web/web_components')
-rw-r--r--files/de/web/web_components/custom_elements/index.html258
-rw-r--r--files/de/web/web_components/index.html222
-rw-r--r--files/de/web/web_components/using_custom_elements/index.html249
3 files changed, 729 insertions, 0 deletions
diff --git a/files/de/web/web_components/custom_elements/index.html b/files/de/web/web_components/custom_elements/index.html
new file mode 100644
index 0000000000..2f29481161
--- /dev/null
+++ b/files/de/web/web_components/custom_elements/index.html
@@ -0,0 +1,258 @@
+---
+title: Benutzerdefinierte Elemente
+slug: Web/Web_Components/Custom_Elements
+translation_of: Web/Web_Components/Using_custom_elements
+---
+<p>Benutzerdefinierte Elemente sind stellen die Möglichkeit bereit, benutzerdefinierte HTML-<a href="/en-US/docs/Glossary/Element">Elements</a> zu schaffen. Sie können eigenes durch JavaScript beschriebenes Verhalten und CSS-Styling haben. Sie sind Teil der <a href="/en-US/docs/Web/Web_Components">Web-Components</a>, können aber auch unabhängig von diesen benutzt werden.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Benutzerdefinierte Elemente gelten erst seit Kurzem als stabil definiert und Teile des MDN weisen Dokumentation für veraltete APIs früherer Spezifikationsentwürfe auf.</p>
+</div>
+
+<p>Obwohl es bereits möglich war, benutzerdefinierte Tag-Namen wie <code>&lt;mytag&gt;</code> zu schaffen, sie mit CSS zu stylen und via JavaScript ihr Verhalten zu beschreiben, haben benutzerdefinierte Elemente ihre Daseinsberechtigung. Ihr großer Vorteil ist das Vorhandensein so genannter <em>Lebenszyklus-Reaktionen</em>, die es erlauben, Methoden zu bestimmten Momenten des "Lebenszyklus" des Elementes aufzurufen. So kann beispielsweise Verhalten beschrieben werden, dass ausgeführt wird, wenn das Element dem DOM hinzugefügt wird ("connected"), wenn es aus diesem entfernt wird ("disconnected") oder sich seine Attribute ändern.</p>
+
+<p>Die Schlüsselmethode für benutzerdefinierte Elemente ist die {{domxref("CustomElementRegistry.define()")}}-Methode, die benutzt werden kann, um ein neues benutzerdefinierte Elemente zu erschaffen. Dieses neue Element wird dann für jede seiner Instanzen diese neue Klasse anstelle des standardmäßig verwendeten {{domxref("HTMLUnknownElement")}} benutzen. Benutzerdefinierte Elemente können auch auf nativen Elementen wie  <code>&lt;button&gt;</code> basieren, indem sie folgende Syntax benutzen: <code>&lt;button is="my-button"&gt;</code> Sie werden dann <em>benutzerdefinierte eingebaute Elemente </em>genannt.</p>
+
+<h2 id="Methoden_benutzerdefinierter_Elemente">Methoden benutzerdefinierter Elemente</h2>
+
+<p>Benutzerdefinierte Elemente besitzen folgende Methoden:</p>
+
+<dl>
+ <dt>constructor()</dt>
+ <dd>Wird aufgerufen, wenn eine Element erzeugt und erweitert wird.</dd>
+ <dt>connectedCallback()</dt>
+ <dd>Wird aufgerufen, wenn das Element in das Dokument eingefügt wird, auch wenn es nur der Shadow Tree ist</dd>
+ <dt>disconnectedCallback()</dt>
+ <dd>Wird aufgerufen, wenn das Element aus dem Dokument entfernt wird.</dd>
+ <dt>attributeChangedCallback(attributeName, oldValue, newValue, namespace)</dt>
+ <dd>Wird aufgerufen, wenn Attribute des Elements geändert, angefügt, entfernt oder ersetzt werden. Wird nur für <a href="#Observed_attributes">beobachtete Attribute</a> aufgerufen.</dd>
+ <dt>adoptedCallback(oldDocument, newDocument)</dt>
+ <dd>Wird aufgerufen, wenn das Element in ein neues Dokument übernommen wird.</dd>
+</dl>
+
+<h2 id="Beispiele">Beispiele</h2>
+
+<p>Benutzerdefinierte Elemente müssen die <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes"><code>class</code> Syntax</a> benutzen, die in neueren JavaScript-Versionen bereit steht.</p>
+
+<p>HTML-Datei:</p>
+
+<pre class="brush: html">Wenn unter diesem Text nichts steht, unterstützt ihr Browser keine benutzerdefinierten Elemente.
+&lt;x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"&gt;&lt;/x-product&gt;
+&lt;x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"&gt;&lt;/x-product&gt;
+&lt;x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"&gt;&lt;/x-product&gt;</pre>
+
+<p>JS-Datei:</p>
+
+<pre class="brush: js">// Klasse für das Element erzeugen
+class XProduct extends HTMLElement {
+ constructor() {
+ // super() muss immer als erstes im Konstruktor aufgerufen werden
+ super();
+
+ // Shadow-Root erzeugen
+ var shadow = this.attachShadow({mode: 'open'});
+
+ // Standard img-Element erzeugen und Attribute setzen
+ var img = document.createElement('img');
+ img.alt = this.getAttribute('data-name');
+ img.src = this.getAttribute('data-img');
+ img.width = '150';
+ img.height = '150';
+ img.className = 'product-img';
+
+ // Bild der Shadow-Root hinzufügen.
+ shadow.appendChild(img);
+
+ // Event-Listener zum Bild hinzufügen.
+ img.addEventListener('click', () =&gt; {
+ window.location = this.getAttribute('data-url');
+ });
+
+ // Link zum Produkt erzeugen.
+ var link = document.createElement('a');
+ link.innerText = this.getAttribute('data-name');
+ link.href = this.getAttribute('data-url');
+ link.className = 'product-name';
+
+ // Link der Shadow-Root hinzufügen.
+ shadow.appendChild(link);
+ }
+}
+
+// Neues Element definieren
+customElements.define('x-product', XProduct);
+</pre>
+
+<p>CSS-Datei:</p>
+
+<pre class="brush: css">body {
+  background: #F7F7F7;
+}
+
+x-product {
+  display: inline-block;
+  float: left;
+  margin: 0.5em;
+  border-radius: 3px;
+  background: #FFF;
+  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
+  font-family: Helvetica, arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+}
+
+x-product::slotted(.product-img) {
+  cursor: pointer;
+  background: #FFF;
+  margin: 0.5em;
+}
+
+x-product::slotted(.product-name) {
+  display: block;
+  text-align: center;
+  text-decoration: none;
+  color: #08C;
+  border-top: 1px solid #EEE;
+  font-weight: bold;
+  padding: 0.75em 0;
+}
+</pre>
+
+<p><a id="live_example" name="live_example">Unten kann das Live-Beispiel des obigen Codes gesehen werden:</a></p>
+
+<p>{{ EmbedLiveSample('Example', '1500', '250', '', 'Web/Web_Components/Custom_Elements') }}</p>
+
+<h2 id="Beobachtete_Attribute">Beobachtete Attribute</h2>
+
+<p>Um benachrichtigt zu werden, wenn Attribute verändert werden, muss eine Liste von beobachteten Attributen bei der Initialisierung des Elements angelegt werden, in dem eine statische <code>observedAttributes</code> get-Methode der Klasse des Elementes hinzugefügt wird, die ein Array mit den entsprechenden Attributsnamen zurückgibt.</p>
+
+<p>JS-Datei:</p>
+
+<pre class="brush: js">class HelloElement extends HTMLElement {
+ // Das 'name'-Attribut beobachten.
+ static get observedAttributes() {return ['name']; }
+
+ // Auf Attributsänderungen reagieren.
+ attributeChangedCallback(attr, oldValue, newValue) {
+ if (attr == 'name') {
+ this.textContent = `Hello, ${newValue}`;
+ }
+ }
+}
+
+// Neues Element definieren
+customElements.define('hello-element', HelloElement);
+</pre>
+
+<p>HTML-Datei:</p>
+
+<pre class="brush: html">&lt;hello-element name="Anita"&gt;&lt;/hello-element&gt;</pre>
+
+<p><a id="live_example" name="live_example">Unten kann das Live-Beispiel des obigen Codes gesehen werden:</a></p>
+
+<p>{{ EmbedLiveSample('Observed_attributes', '750', '100', '', 'Web/Web_Components/Custom_Elements') }}</p>
+
+<h2 id="Spezifikationen">Spezifikationen</h2>
+
+<p>Benutzerdefinierte Elemente sind in der folgenden Spezifikation definiert:</p>
+
+<table class="spec-table standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Spezifikation</th>
+ <th scope="col">Status</th>
+ <th scope="col">Kommentar</th>
+ </tr>
+ <tr>
+ <td><a href="https://html.spec.whatwg.org/multipage/scripting.html#custom-elements">The HTML Standard: Custom elements</a></td>
+ <td>LS</td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
+
+<p>{{CompatibilityTable}}</p>
+
+<div id="compat-desktop">
+<table class="compat-table">
+ <tbody>
+ <tr>
+ <th>Feature</th>
+ <th>Firefox (Gecko)</th>
+ <th>Chrome</th>
+ <th>Internet Explorer</th>
+ <th>Opera</th>
+ <th>Safari</th>
+ </tr>
+ <tr>
+ <td>Grundlegende Unterstützung</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatChrome(59.0)}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatOpera(47.0)}}</td>
+ <td>10.1</td>
+ </tr>
+ <tr>
+ <td>Benutzerdefinierte eingebaute Elemente</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatChrome(59.0)}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatOpera(47.0)}}</td>
+ <td>{{CompatNo}}</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<div id="compat-mobile">
+<table class="compat-table">
+ <tbody>
+ <tr>
+ <th>Feature</th>
+ <th>Firefox Mobile (Gecko)</th>
+ <th>Chrome for Android</th>
+ <th>IE Mobile</th>
+ <th>Opera Mobile</th>
+ <th>Safari Mobile</th>
+ </tr>
+ <tr>
+ <td>Grundlegende Unterstützung</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatChrome(56.0)}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatOpera(47.0)}}</td>
+ <td>10.1</td>
+ </tr>
+ <tr>
+ <td>Benutzerdefinierte eingebaute Elemente</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatChrome(56.0)}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatOpera(47.0)}}</td>
+ <td>{{CompatNo}}</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<p>1. Firefox hat eine "dom.webcomponents.enabled"-Eigenschaft in about:config, dennoch ist sind benutzerdefinierte Elemente nicht verfügbar, wenn diese auf <strong>true</strong> gesetzt wurde.</p>
+
+<h2 id="Related">Related</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry">The Custom Element Registry</a>
+
+ <ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define">define()</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get">get()</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/whenDefined">whenDefined()</a></li>
+ </ul>
+ </li>
+</ul>
+
+<h2 id="Resources">Resources</h2>
+
+<ul>
+ <li><a href="https://developers.google.com/web/fundamentals/primers/customelements/">Custom elements v1: reusable web components - Google Developers tutorial</a></li>
+</ul>
diff --git a/files/de/web/web_components/index.html b/files/de/web/web_components/index.html
new file mode 100644
index 0000000000..bc5e676475
--- /dev/null
+++ b/files/de/web/web_components/index.html
@@ -0,0 +1,222 @@
+---
+title: Web Components
+slug: Web/Web_Components
+tags:
+ - Benutzerdefinierte Elemente
+ - Components
+ - JavaScript
+ - Landing
+ - Overview
+ - Schatten-DOM
+ - Template
+ - Web Components
+ - Webkomponenten
+ - custom elements
+ - shadow dom
+ - slot
+ - Überblick
+translation_of: Web/Web_Components
+---
+<div>{{DefaultAPISidebar("Webkomponenten")}}</div>
+
+<div class="summary">
+<p>Webkomponenten sind eine Gruppe von Web-Technologien, die es ermöglichen, benutzerdefinierte, wiederverwendbare HTML Elemente zu erstellen, deren Funktionalität gekapselt ist und damit vollständig getrennt von anderem Code.</p>
+
+<h2 id="Konzept_und_Anwendung">Konzept und Anwendung</h2>
+</div>
+
+<p>Unter Softwareentwicklern ist allgemein anerkannt, Code weitestgehend wiederzuverwenden. Für benutzerdefinierte Markup-Strukturen war dies bekanntermaßen nicht ganz so einfach. Denken Sie nur an das komplexe HTML- (sowie CSS- und Skript-)Konglomerat, das teilweise notwendig war, um benutzerdefinierte UI-Steuerelemente zu erstellen; und wie die mehrfache Verwendung derartiger benutzerdefinierter Elemente auf einer Seite zu einem völlig undurchsichtigen Wirrwar führen kann, wenn man nicht äußerst sorgfältig vorgeht.</p>
+
+<p>Webkomponenten zielen darauf ab, diese Probleme zu lösen. Bestehend aus drei Haupttechnologien, die gemeinsam eingesetzt werden können, um unterschiedliche und vielseitige benutzerdefinierte Elemente mit in sich gekapselter Funktionalität zu erstellen, die beliebig oft wiederverwendet werden können, ohne befürchten zu müssen, dass unterschiedlicher Code sich gegenseitig beeinflusst oder stört:</p>
+
+<ul>
+ <li><strong>Benutzerdefinierte Elemente</strong>: Ein Satz von JavaScript APIs, die es ermöglichen, benutzerdefinierte Elemente sowie deren Verhalten zu definieren, die dann anschließend beliebig auf Ihrer Benutzeroberfläche verwendet werden können.</li>
+ <li><strong>Shadow DOM</strong>: Ein Satz von JavaScript APIs, um einen Baum aus darin gekapselten "Schatten"-DOM-Elementen an ein Element anzufügen, der unabhängig vom DOM des Hauptdokuments gerendert wird, sowie um die dazugehörige Funktionalität zu steuern. Mit Hilfe dieser Technologie verbleiben die Ausprägungen solcher Elemente privat, sodass Skripte und Styles auf sie angewendet werden können, ohne dass sie mit anderen Teilen des Dokuments kollidieren.</li>
+ <li><strong>HTML-Vorlagen</strong>: Die {{HTMLElement("template")}}- und {{HTMLElement("slot")}}-Elemente gestatten es, Markup-Vorlagen zu schreiben, die nicht auf der dargestellten Seite abgebildet werden. Diese können dann als Grundlage für benutzerdefinierte Elemente mehrere Male wiederverwendet werden.</li>
+</ul>
+
+<p>Die grundsätzliche Herangehensweise für das Implementieren einer Webkomponente sieht im Allgemeinen so aus:</p>
+
+<ol>
+ <li>Erstellen einer Klasse oder einer Funktion, in der die Funktionalität der Webkomponente festgelegt wird. Falls Sie hierzu eine Klasse einsetzen, dann verwenden Sie die ECMAScript 2015-Syntax (siehe auch <a href="/de-DE/docs/Web/JavaScript/Reference/Classes">Klassen</a>).</li>
+ <li>Registrieren des neuen benutzerdefinierten Elements mithilfe der {{domxref("CustomElementRegistry.define()")}}-Methode. Dieser Methode werden der zu definierende Elementname, die Klasse bzw. Funktion, in der die Funktionalität definiert ist, sowie optional das Element, von dem das neue benutzerdefinierte Element erbt, übergeben.</li>
+ <li>Falls erforderlich: Anfügen eines Schatten-DOMs zum benutzerdefinierten Element mithilfe der {{domxref("Element.attachShadow()")}}-Methode. Kindelemente, Ereignisbehandlungsroutinen usw. werden dem Schatten-DOM unter Verwendung der üblichen DOM-Methoden hinzugefügt.</li>
+ <li>Falls erforderlich: Definieren einer HTML-Vorlage mithilfe von {{htmlelement("template")}} und {{htmlelement("slot")}}. Auch hier werden die üblichen DOM-Methoden verwendet, um die HTML-Vorlage anschließend zu kopieren und zum Schatten-DOM hinzuzufügen.</li>
+ <li>Das so geschaffene benutzerdefinierte Element kann überall auf der Seite eingefügt werden — ebenso wie ein normales HTML-Element.</li>
+</ol>
+
+<h2 id="Übungen">Übungen</h2>
+
+<dl>
+ <dt><a href="/de-DE/docs/Web/Web_Components/Using_custom_elements">Benutzerdefinierte Elemente</a></dt>
+ <dd>Zeigt, wie benutzerdefinierte Elemente eingesetzt werden können, um einfache Webkomponenten zu erzeugen, die Rückruffunktionen (Callbacks) innerhalb des Lebenszyklus' einer Webkomponente, sowie einige weitere, fortgeschrittene Bestandteile benutzerdefinierter Elemente.</dd>
+ <dt><a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a></dt>
+ <dd>Wirft einen Blick auf die Grundlagen des Schatten-DOMs: Wie ein Schatten-DOM an ein Element angefügt wird, wie Elemente zum Baum des Schatten-DOMs hinzugefügt werden, wie Stile auf sie angewendet werden, und weiteres mehr.</dd>
+ <dt><a href="/de-DE/docs/Web/Web_Components/Using_templates_and_slots">Vorlagen und Einschübe</a></dt>
+ <dd>Zeigt, wie eine wiederverwendbare HTML-Struktur mithilfe der {{htmlelement("template")}} und {{htmlelement("slot")}}-Elemente definiert und diese Struktur anschließend innerhalb von Webkomponenten eingesetzt wird.</dd>
+</dl>
+
+<h2 id="Referenz">Referenz</h2>
+
+<h3 id="Benutzerdefinierte_Elemente">Benutzerdefinierte Elemente</h3>
+
+<dl>
+ <dt>{{domxref("CustomElementRegistry")}}</dt>
+ <dd>Beinhaltet Methoden in Bezug auf benutzerdefinierte Elemente, insbesondere die {{domxref("CustomElementRegistry.define()")}}-Methode, die zum Registrieren neuer benutzerdefinierter Elemente verwendet wird, damit sie in einem Dokument verwendet werden können.</dd>
+ <dt>{{domxref("Window.customElements")}}</dt>
+ <dd>Liefert eine Referenz auf ein <code>CustomElementRegistry</code>-Objekt.</dd>
+ <dt><a href="/de-DE/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks">Rückruffunktionen innerhalb des Lebenszyklus</a></dt>
+ <dd>Spezielle Callback-Funktionen, die innerhalb der Klasse des benutzerdefinierten Steuerelements definiert sind und dessen Verhalten steuern:
+ <ul>
+ <li><code>connectedCallback</code>: Wird aufgerufen, wenn das benutzerdefinierte Element mit dem DOM des Dokuments verbunden ist.</li>
+ <li><code>disconnectedCallback</code>: Wird aufgerufen, wenn das benutzerdefinierte Element vom DOM des Dokuments abgetrennt wird.</li>
+ <li><code>adoptedCallback</code>: Wird aufgerufen, wenn das benutzerdefinierte Element zu einem neuen Dokument verschoben wird.</li>
+ <li><code>attributeChangedCallback</code>: Wird aufgerufen, wenn eines der Attribute des benutzerdefinierten Elements hinzugefügt, gelöscht oder verändert wird.</li>
+ </ul>
+ </dd>
+ <dt>Erweiterungen, um benutzerdefinierte eingebaute Elemente zu erzeugen</dt>
+ <dd>
+ <ul>
+ <li>Das globale {{htmlattrxref("is")}}-Attribut dient dazu, ein Standard-HTML-Element anzugeben, das sich wie ein benutzerdefiniertes Element verhalten soll.</li>
+ <li>Die "is"-Option der {{domxref("Document.createElement()")}}-Methode dient dazu, eine Instanz eines zuvor registrierten benutzerdefinierten Standard-HTML-Elements zu erzeugen.</li>
+ </ul>
+ </dd>
+ <dt>CSS Pseudoklassen</dt>
+ <dd>Pseudoklassen, die sich speziell auf benutzerdefinierte Elemente beziehen:
+ <ul>
+ <li>{{cssxref(":defined")}}: Trifft auf jedes definierte Element zu, einschließlich eingebauter und benutzerdefinierter Elemente, die mithilfe von <code>CustomElementRegistry.define()</code> definiert sind.</li>
+ <li>{{cssxref(":host")}}: Wählt das jeweilige Container-Element des <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOMs</a>, auf das die jeweilige CSS-Regel angewendet wird.</li>
+ <li>{{cssxref(":host()")}}: Wählt das Container-Element des <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOMs</a>, auf das die jeweilige CSS-Regel angewendet wird — aber nur dann, wenn der Selektor, der als Funktionsargument übergeben wird, auf das jeweilige Container-Element passt.</li>
+ <li>{{cssxref(":host-context()")}}: Wählt das Container-Element des <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOMs</a>, auf das die jeweilige CSS-Regel angewendet wird — aber nur dann, wenn der Selektor, der als Funktionsargument übergeben wird, auf die dem jeweiligen Container-Element übergeordnete Hierarchie innerhalb des DOMs passt.</li>
+ </ul>
+ </dd>
+</dl>
+
+<h3 id="Schatten-DOM">Schatten-DOM</h3>
+
+<dl>
+ <dt>{{domxref("ShadowRoot")}}</dt>
+ <dd>Repräsentiert die Wurzel-Node eines <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baums.</dd>
+ <dt>{{domxref("DocumentOrShadowRoot")}}</dt>
+ <dd>Ein Mixin, das diejenigen Merkmale definiert, die sowohl in einem Dokument als auch in der Wurzel-Node eines <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baums verfügbar sind.</dd>
+ <dt>{{domxref("Element")}}-Erweiterungen</dt>
+ <dd>Erweiterungen zur <code>Element</code>-Schnittstelle, die sich auf das <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a> beziehen:
+ <ul>
+ <li>Die {{domxref("Element.attachShadow()")}}-Methode fügt einen <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baum an das angegebene Element an.</li>
+ <li>Die {{domxref("Element.shadowRoot")}}-Eigenschaft liefert die Wurzel-Node des <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baums des angegebenen Elements; oder <code>null</code>, falls kein <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baum angefügt wurde.</li>
+ </ul>
+ </dd>
+ <dt>Wichtige {{domxref("Node")}}-Erweiterungen</dt>
+ <dd>Erweiterung zur <code>Node</code>-Schnittstelle, die sich auf das <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a> beziehen:
+ <ul>
+ <li>Die {{domxref("Node.getRootNode()")}}-Methode liefert die Wurzel-Node des Kontextobjekts, die optional auch die Wurzel-Node des <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baums enthält, sofern verfügbar.</li>
+ <li>Die {{domxref("Node.isConnected")}}-Eigenschaft liefert einen booleschen Wert, der angibt, ob eine Node (direkt oder indirekt) mit dem Kontextobjekt verbunden ist oder nicht. Dies ist beispielsweise das {{domxref("Document")}}-Objekt im Falle eines normalen DOMs bzw. das {{domxref("ShadowRoot")}}-Objekt im Falle eines <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOMs</a>.</li>
+ </ul>
+ </dd>
+ <dt>{{domxref("Event")}}-Erweiterungen</dt>
+ <dd>Erweiterungen der <code>Event</code>-Schnittstelle, die sich auf das <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a> beziehen:
+ <ul>
+ <li>{{domxref("Event.composed")}}: Liefert einen booleschen Wert, der angibt, ob ein Ereignis sich vom <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a> in das normale DOM fortsetzt (<code>true</code>), oder nicht (<code>false</code>).</li>
+ <li>{{domxref("Event.composedPath")}}: Liefert den Pfad des Ereignisses (Objekte, deren Ereignisbehandlungsroutinen aufgerufen werden). Ausgeschlossen hiervon sind Nodes in <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Bäumen, wenn die Wurzel-Node des <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baums mit <code>{{domxref("ShadowRoot.mode")}} = "closed"</code> erstellt wurde.</li>
+ </ul>
+ </dd>
+</dl>
+
+<h3 id="HTML-Vorlagen">HTML-Vorlagen</h3>
+
+<dl>
+ <dt>{{htmlelement("template")}}</dt>
+ <dd>Beinhaltet ein HTML-Fragment, das nicht dargestellt wird, wenn das beinhaltende Dokument geladen wird. Es kann aber zur Laufzeit mit Hilfe von JavaScript angezeigt werden. Es wird hauptsächlich als Grundstruktur für benutzerdefinierte Elemente verwendet. Die dazugehörige DOM-Schnittstelle lautet: {{domxref("HTMLTemplateElement")}}.</dd>
+ <dt>{{htmlelement("slot")}}</dt>
+ <dd>Ein Platzhalter innerhalb einer Webkomponente, die mit benutzerdefiniertem Markup gefüllt werden kann. Auf diese Weise lassen sich unterschiedliche DOM-Fragmente mit der gleichen HTML-Vorlage erstellen, die alle gemeinsam dargestellt werden können. Die dazugehörige DOM-Schnittstelle lautet: {{domxref("HTMLSlotElement")}}.</dd>
+ <dt>Das globale <code><a href="/de-DE/docs/Web/HTML/Global_attributes/slot">slot</a></code> HTML-Attribut</dt>
+ <dd>Weist einem Element einen Einschub innerhalb eines <a href="/de-DE/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Baums zu.</dd>
+ <dt>{{domxref("Slotable")}}</dt>
+ <dd>Ein Mixin, das sowohl von {{domxref("Element")}}- als auch {{domxref("Text")}}-Nodes implementiert wird. Es definiert Methoden, die es den jeweiligen Nodes erlauben, Inhalt eines {{htmlelement("slot")}}-Elements zu werden. Das Mixin definiert ein Attribute: {{domxref("Slotable.assignedSlot")}}, das eine Referenz auf den Einschub liefert, in den die Node eingefügt wurde.</dd>
+</dl>
+
+<dl>
+ <dt>{{domxref("Element")}}-Erweiterungen</dt>
+ <dd>Erweiterungen der <code>Element</code>-Schnittstelle, die sich auf Einschübe beziehen:
+ <ul>
+ <li>{{domxref("Element.slot")}}: Liefert den Namen des Einschubs, der dem Element hinzugefügt wurde.</li>
+ </ul>
+ </dd>
+ <dt>CSS Pseudoelemente</dt>
+ <dd>Pseudoelemente, die sich speziell auf Einschübe beziehen:
+ <ul>
+ <li>{{cssxref("::slotted")}}: Trifft auf jeden Inhalt zu, der einem Einschub hinzugefügt wurde.</li>
+ </ul>
+ </dd>
+ <dt>Das {{event("slotchange")}}-Ereignis</dt>
+ <dd>Wird auf einer {{domxref("HTMLSlotElement")}}-Instanz ({{htmlelement("slot")}}-Element) ausgelöst, wenn die Node(s), die sich im Einschub befinden, verändern.</dd>
+</dl>
+
+<h2 id="Beispiele">Beispiele</h2>
+
+<p>Sie finden eine Reihe von Beispielen in unserem <a href="https://github.com/mdn/web-components-examples">web-components-examples</a> GitHub-Repository. Diesem Repository werden über die Zeit weitere Beispiele hinzugefügt.</p>
+
+<h2 id="Spezifikationen">Spezifikationen</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Spezifikation</th>
+ <th scope="col">Status</th>
+ <th scope="col">Kommentar</th>
+ </tr>
+ <tr>
+ <td>{{SpecName("HTML WHATWG","scripting.html#the-template-element","&lt;template&gt; element")}}</td>
+ <td>{{Spec2("HTML WHATWG")}}</td>
+ <td>Definition von {{HTMLElement("template")}}.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName("HTML WHATWG","scripting.html#the-slot-element","&lt;slot&gt; element")}}</td>
+ <td>{{Spec2("HTML WHATWG")}}</td>
+ <td>Definition von {{HTMLElement("slot")}}.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName("HTML WHATWG","custom-elements.html#custom-elements","custom elements")}}</td>
+ <td>{{Spec2("HTML WHATWG")}}</td>
+ <td>Definition von <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements">benutzerdefinierten HTML Elementen</a>.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName("DOM WHATWG","#shadow-trees","shadow trees")}}</td>
+ <td>{{Spec2("DOM WHATWG")}}</td>
+ <td>Definition des <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOMs</a>.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName("HTML Imports", "", "")}}</td>
+ <td>{{Spec2("HTML Imports")}}</td>
+ <td>Erste <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/HTML_Imports">HTML Importe</a>-Definition.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName("Shadow DOM", "", "")}}</td>
+ <td>{{Spec2("Shadow DOM")}}</td>
+ <td>Erste <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM">Schatten-DOM</a>-Definition.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
+
+<p>Grundsätzlich:</p>
+
+<ul>
+ <li>Webkomponenten werden standardmäßig von Firefox (ab Version 63), Chrome, und Opera unterstützt.</li>
+ <li>Safari unterstützts eine Reihe von Merkmalen von Webkomponenten, aber weniger als die oben genannten Browser.</li>
+ <li>Edge arbeitet an einer Implementation.</li>
+</ul>
+
+<p>Um detaillierte Informationen zur Unterstützung spezifischer Merkmale einzelner Browser zu erhalten, ziehen sie bitte die oben genannten Referenzdokumente zu Rate.</p>
+
+<h2 id="Siehe_auch">Siehe auch</h2>
+
+<ul>
+ <li><a href="https://www.webcomponents.org/">webcomponents.org</a> — Website, die Beispiele, Übungen und weiterführende Informationen zu Webkomponenten bietet.</li>
+ <li><a href="https://github.com/hybridsjs/hybrids">Hybrids</a> — Open-Source Webkomponenten-Bibliothek, die simple Objekte und reine Funktionen der <code>class</code> und <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">this</span></font> Syntax vorzieht. Die Bibliothek bietet eine einfache, funktionale API, um benutzerdefinierte Elemente zu erzeugen.</li>
+ <li><a href="https://www.polymer-project.org/">Polymer</a> — Googles Webkomponenten-Framework — eine Sammlung von Polyfills, Erweiterungen und Beispielen. Dieses Framework ist aktuell der einfachste Weg, Webkomponenten browserübergreifend einzusetzen.</li>
+ <li><a href="https://github.com/devpunks/snuggsi#readme">Snuggsi.es</a> — Einfacher Zugriff auf Webkomponenten in ~1kB, <em>inklusive Polyfill</em> — Alles, was Sie benötigen, ist ein Browser und ein grundsätzliches Verständnis von HTML, CSS und JavaScript Klassen, um zu starten.</li>
+ <li><a href="https://github.com/slimjs/slim.js">Slim.js</a> — Open-Source Webkomponenten-Bibliothek — eine hochperformante Bibliothek, um schnell und einfach Komponenten zu erstellen. Durch Plug-ins erweiterbar und Cross-Framework-kompatibel.</li>
+ <li><a href="https://www.htmlelements.com/">Smart.js</a> — Webkomponenten-Bibliothek mit einer einfachen API, um browserübergreifend benutzerdefinierte Elemente zu erstellen. </li>
+</ul>
diff --git a/files/de/web/web_components/using_custom_elements/index.html b/files/de/web/web_components/using_custom_elements/index.html
new file mode 100644
index 0000000000..9486ce75e1
--- /dev/null
+++ b/files/de/web/web_components/using_custom_elements/index.html
@@ -0,0 +1,249 @@
+---
+title: Benutzerdefinierte Elemente
+slug: Web/Web_Components/Using_custom_elements
+translation_of: Web/Web_Components/Using_custom_elements
+---
+<div>{{DefaultAPISidebar("Web Components")}}</div>
+
+<p class="summary">Eines der Hauptmerkmale des Web Components Standards ist die Möglichkeit, benutzerdefinierte Elemente (custom elements) zu erstellen, die ihre Funktionalität auf einer HTML-Seite kapseln, anstatt sich mit einem langen, verschachtelten Stapel von Elementen begnügen zu müssen, die zusammen eine benutzerdefinierte Seitenfunktion bereitstellen. Dieser Artikel stellt die Verwendung von benutzerdefinierten HTML-Elementen vor.</p>
+
+<div class="note">
+<p><strong>Hinweis</strong>: Benutzerdefinierte Elemente werden standardmäßig in Chrome und Opera unterstützt. Firefox ist sehr weit in der Entwicklung; sie sind derzeit verfügbar, wenn Sie die Einstellungen <code>dom.webcomponents.shadowdom.enabled </code>und <code>dom.webcomponents.customelements.enabled</code> auf <code>true</code> setzen. Die Implementierung von Firefox soll in der Version 60/61 standardmäßig aktiviert werden. Safari unterstützt bisher nur autonome benutzerdefinierte Elemente, und Edge arbeitet auch an einer Implementierung.</p>
+</div>
+
+<h2 id="High-Level-Ansicht">High-Level-Ansicht</h2>
+
+<p>Der Controller von benutzerdefinierten Elementen in einem Web-Dokument ist das Objekt {{domxref("CustomElementRegistry")}} - mit diesem Objekt können Sie ein benutzerdefiniertes Element auf der Seite registrieren, Informationen darüber zurückgeben, welche benutzerdefinierten Elemente registriert sind etc.</p>
+
+<p>Um ein benutzerdefiniertes Element auf der Seite zu registrieren, verwenden Sie die Methode {{domxref("CustomElementRegistry.define()")}}. Das sind die Argumente:</p>
+
+<ul>
+ <li>Ein {{domxref("DOMString")}} repräsentiert den Namen, den Sie dem Element geben. Beachten Sie, dass benutzerdefinierte Elementnamen einen <a href="https://stackoverflow.com/questions/22545621/do-custom-elements-require-a-dash-in-their-name">Bindestrich erfordern</a>; sie können keine einzelnen Wörter sein.</li>
+ <li>Ein <a href="/en-US/docs/Web/JavaScript/Reference/Classes">Klassenobjekt</a>, das das Verhalten des Elements definiert.</li>
+ <li>Optional ein Optionsobjekt, das eine <code>extends</code>Eigenschaft enthält, die das eingebaute Element angibt, von dem Ihr Element erbt, falls vorhanden.</li>
+</ul>
+
+<p>So können wir z.B. ein benutzerdefiniertes <a href="https://mdn.github.io/web-components-examples/word-count-web-component/">Wortzählelement</a> wie dieses definieren:</p>
+
+<pre class="brush: js">customElements.define('word-count', WordCount, { extends: 'p' });</pre>
+
+<p>Das Element heißt <code>word-count</code>, sein Klassenobjekt ist WordCount, und es erweitert das Element {{htmlelement("p")}}.</p>
+
+<p>Das Klassenobjekt eines benutzerdefinierten Elements wird mit der ES 2015 Standardsyntax einer Klasse geschrieben. Zum Beispiel ist <code>WordCount</code>so aufgebaut:</p>
+
+<pre class="brush: js">class WordCount extends HTMLParagraphElement {
+ constructor() {
+ // Always call super first in constructor
+ super();
+
+ // Element functionality written in here
+
+ ...
+ }
+}</pre>
+
+<p>Dies ist nur ein einfaches Beispiel, aber es gibt noch mehr, was Sie hier tun können. Es ist möglich, spezifische Lifecycle-Callbacks innerhalb des Konstruktors zu definieren, die an bestimmten Stellen im Lebenszyklus des Elements ablaufen. Zum Beispiel wird <code>connectedCallback </code>aufgerufen, wenn das benutzerdefinierte Element zum ersten Mal mit dem DOM des Dokuments verbunden wird, während <code>attributeChangedCallback</code> aufgerufen wird, wenn eines der Attribute des benutzerdefinierten Elements hinzugefügt, entfernt oder geändert wird.</p>
+
+<p>Im untenstehenden Kapitel {{anch("Using the lifecycle callbacks")}} wirst du mehr über Lifecycle-Callbacks erfahren.</p>
+
+<p>Es gibt zwei Arten von benutzerdefinierten Elementen:</p>
+
+<ul>
+ <li><strong>Autonome benutzerdefinierte Elemente</strong> sind eigenständig, d.h. sie erben nicht von standardisierten HTML-Elementen. Du kannst diese Art von benutzerdefinierten Elementen verwenden, indem du ein HTML-Element mit dem entsprechenden Namen erzeugst, z.B. <code>&lt;popup-info&gt;</code> oder <code>document.createElement("popup-info")</code>.</li>
+ <li><strong>Benutzerdefinierte Standardelemente</strong> erben von standardisierten HTML-Elementen. Beim Erstellen eines solchen Elements musst du angeben, von welchem standardisierten HTML-Element geerbt wird (vgl. obige Beispiele). Um ein benutzerdefiniertes Standardelement zu verwenden, erstellst du Objekt des Basiselements mit dem Attribut (oder der Eigenschaft) {{htmlattrxref("is")}}, z.B. <code>&lt;p is="word-count"&gt;</code> oder <code>document.createElement("p", { is: "word-count" })</code>. </li>
+</ul>
+
+<h2 id="Weitere_einfache_Beispiele">Weitere einfache Beispiele</h2>
+
+<p>Wir gehen durch einige einfache Beispiele um etwas detaillierter zu zeigen wie benutzerdefinierte Elemente erzeugt werden. </p>
+
+<h3 id="Autonome_benutzerdefinierte_Elemente"><strong>Autonome benutzerdefinierte Elemente</strong></h3>
+
+<p>Wir betrachten ein Beispiel eines autonomen benutzerdefinierte Elementes —<br>
+ <code><a href="https://github.com/mdn/web-components-examples/tree/master/popup-info-box-web-component">&lt;popup-info-box&gt;</a></code> (siehe hierzu <a href="https://mdn.github.io/web-components-examples/popup-info-box-web-component/">live example</a>).</p>
+
+<p>Dieses Element nimmt ein Icon und einen Textstring entgegen und fügt das Icon in die Seite ein. Erhält das Icon den Focus, wird der Text in einem Popup-Dialog angezeigt um mehr Information anzubieten</p>
+
+<p>Folgendes  JavaScript File definiert eine Klasse  <code>PopUpInfo</code>, welches das {{domxref("HTMLElement")}} erweitert. Autonome benutzerdefinierte Elemente erweitern nahezu immer das <code>HTMLElement</code>.</p>
+
+<pre class="brush: js">class PopUpInfo extends HTMLElement {
+ constructor() {
+ // Always call super first in constructor
+ super();
+
+ // write element functionality in here
+
+ ...
+ }
+}</pre>
+
+<p>Dieser Code enthält die {{jsxref("Classes.constructor","constructor")}} Definition für diese Klasse, welche immer mit einem Aufruf von  <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/super">super()</a></code> beginnt, damit die korrekte Prototypkette erzeugt wird.</p>
+
+<p>Innerhalb des Konstruktors definieren wir alle Funktionalität welche das Element haben wird wenn von diesem eine Instanz erzeugt wird. </p>
+
+<p>Wir binden eine shadow root an das Element, benutzen DOM-Funktionalität um die interne shadow DOM -Struktur zu erzeugen, welch dann an die shadow root gebunden wird. Abschließend fügen wir der shadow root noch etwas CSS hinzu um diese zu stylen.</p>
+
+<pre class="brush: js">// Create a shadow root
+var shadow = this.attachShadow({mode: 'open'});
+
+// Create spans
+var wrapper = document.createElement('span');
+wrapper.setAttribute('class','wrapper');
+var icon = document.createElement('span');
+icon.setAttribute('class','icon');
+icon.setAttribute('tabindex', 0);
+var info = document.createElement('span');
+info.setAttribute('class','info');
+
+// Take attribute content and put it inside the info span
+var text = this.getAttribute('text');
+info.textContent = text;
+
+// Insert icon
+var imgUrl;
+if(this.hasAttribute('img')) {
+ imgUrl = this.getAttribute('img');
+} else {
+ imgUrl = 'img/default.png';
+}
+var img = document.createElement('img');
+img.src = imgUrl;
+icon.appendChild(img);
+
+// Create some CSS to apply to the shadow dom
+var style = document.createElement('style');
+
+style.textContent = '.wrapper {' +
+// CSS truncated for brevity
+
+// attach the created elements to the shadow dom
+
+shadow.appendChild(style);
+shadow.appendChild(wrapper);
+wrapper.appendChild(icon);
+wrapper.appendChild(info);</pre>
+
+<p>Letztlich registrieren wir unser benutzerdefiniertes Elementen in der <code>CustomElementRegistry</code> mit der Methode <code>define()</code> , in deren Parametern spezifizieren wir den Namen des Elements und dann den Namen der Klasse welche die Funktionalität definiert:</p>
+
+<pre class="brush: js">customElements.define('popup-info', PopUpInfo);</pre>
+
+<p>Jetzt ist unser benutzerdefiniertes Elementen fertig zur Benutzung auf unserer Seite.<br>
+ In unserem HTML sieht das nun so aus:</p>
+
+<pre class="brush: html">&lt;popup-info img="img/alt.png" text="Your card validation code (CVC)
+ is an extra security feature — it is the last 3 or 4 numbers on the
+ back of your card."&gt;</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Die vollständige <a href="https://github.com/mdn/web-components-examples/blob/master/popup-info-box-web-component/main.js"> JavaScript Quelle </a>.</p>
+</div>
+
+<h3 id="Customized_built-in_elements">Customized built-in elements</h3>
+
+<p>Now let's have a look at another customized built in element example — <a href="https://github.com/mdn/web-components-examples/tree/master/expanding-list-web-component">expanding-list</a> (<a href="https://mdn.github.io/web-components-examples/expanding-list-web-component/">see it live also</a>). This turns any unordered list into an expanding/collapsing menu.</p>
+
+<p>First of all, we define our element's class, in the same manner as before:</p>
+
+<pre class="brush: js">class ExpandingList extends HTMLUListElement {
+ constructor() {
+ // Always call super first in constructor
+ super();
+
+ // write element functionality in here
+
+ ...
+ }
+}</pre>
+
+<p>We will not explain the element functionality in any detail here, but you can discover how it works by checking out the source code. The only real difference here is that our element is extending the {{domxref("HTMLUListElement")}} interface, and not {{domxref("HTMLElement")}}. So it has all the characteristics of a {{htmlelement("ul")}} element with the functionality we define built on top, rather than being a standalone element. This is what makes it a customized built-in, rather than an autonomous element.</p>
+
+<p>Next, we register the element using the <code>define()</code> method as before, except that this time it also includes an options object that details what element our custom element inherits from:</p>
+
+<pre class="brush: js">customElements.define('expanding-list', ExpandingList, { extends: "ul" });</pre>
+
+<p>Using the built-in element in a web document also looks somewhat different:</p>
+
+<pre class="brush: html">&lt;ul is="expanding-list"&gt;
+
+ ...
+
+&lt;/ul&gt;</pre>
+
+<p>You use a <code>&lt;ul&gt;</code> element as normal, but specify the name of the custom element inside the <code>is</code> attribute.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Again, you can see the full <a href="https://github.com/mdn/web-components-examples/blob/master/expanding-list-web-component/main.js">JavaScript source code</a> here.</p>
+</div>
+
+<h2 id="Using_the_lifecycle_callbacks">Using the lifecycle callbacks</h2>
+
+<p>You can define several different callbacks inside a custom element's constructor, which fire at different points in the element's lifecycle:</p>
+
+<ul>
+ <li><code>connectedCallback</code>: Invoked when the custom element is first connected to the document's DOM.</li>
+ <li><code>disconnectedCallback</code>: Invoked when the custom element is disconnected from the document's DOM.</li>
+ <li><code>adoptedCallback</code>: Invoked when the custom element is moved to a new document.</li>
+ <li><code>attributeChangedCallback</code>: Invoked when one of the custom element's attributes is added, removed, or changed.</li>
+</ul>
+
+<p>Let's look at an example of these in use. The code below is taken from the <a href="https://github.com/mdn/web-components-examples/tree/master/life-cycle-callbacks">life-cycle-callbacks</a> example (<a href="https://mdn.github.io/web-components-examples/life-cycle-callbacks/">see it running live</a>). This is a trivial example that simply generates a colored square of a fixed size on the page. The custom element looks like this:</p>
+
+<pre class="brush: html">&lt;custom-square l="100" c="red"&gt;&lt;/custom-square&gt;</pre>
+
+<p>The class constructor is really simple — here we attach a shadow DOM to the element, then attach empty {{htmlelement("div")}} and {{htmlelement("style")}} elements to the shadow root:</p>
+
+<pre class="brush: js">var shadow = this.attachShadow({mode: 'open'});
+
+var div = document.createElement('div');
+var style = document.createElement('style');
+shadow.appendChild(style);
+shadow.appendChild(div);</pre>
+
+<p>The key function in this example is <code>updateStyle()</code> — this takes an element, gets its shadow root, finds its <code>&lt;style&gt;</code> element, and adds {{cssxref("width")}}, {{cssxref("height")}}, and {{cssxref("background-color")}} to the style.</p>
+
+<pre class="brush: js">function updateStyle(elem) {
+ var shadow = elem.shadowRoot;
+ var childNodes = shadow.childNodes;
+ for(var i = 0; i &lt; childNodes.length; i++) {
+ if(childNodes[i].nodeName === 'STYLE') {
+ childNodes[i].textContent = 'div {' +
+ ' width: ' + elem.getAttribute('l') + 'px;' +
+ ' height: ' + elem.getAttribute('l') + 'px;' +
+ ' background-color: ' + elem.getAttribute('c');
+ }
+ }
+}</pre>
+
+<p>The actual updates are all handled by the life cycle callbacks, which are placed inside the constructor. The <code>connectedCallback()</code> runs when the element is added to the DOM — here we run the <code>updateStyle()</code> function to make sure the square is styled as defined in its attributes:</p>
+
+<pre class="brush: js">connectedCallback() {
+ console.log('Custom square element added to page.');
+ updateStyle(this);
+}</pre>
+
+<p>the <code>disconnectedCallback()</code> and <code>adoptedCallback()</code> callbacks log simple messages to the console to inform us when the element is either removed from the DOM, or moved to a different page:</p>
+
+<pre class="brush: js">disconnectedCallback() {
+ console.log('Custom square element removed from page.');
+}
+
+adoptedCallback() {
+ console.log('Custom square element moved to new page.');
+}</pre>
+
+<p>The <code>attributeChangedCallback()</code> callback is run whenever one of the element's attributes is changed in some way. As you can see from its properties, it is possible to act on attributes individually, looking at their name, and old and new attribute values. In this case however, we are just running the <code>updateStyle()</code> function again to make sure that the square's style is updated as per the new values:</p>
+
+<pre class="brush: js">attributeChangedCallback(name, oldValue, newValue) {
+ console.log('Custom square element attributes changed.');
+ updateStyle(this);
+}</pre>
+
+<p>Note that to get the <code>attributeChangedCallback()</code> callback to fire when an attribute changes, you have to observe the attributes. This is done by calling the <code>observedAttributes()</code> getter inside custom element class, including inside it a <code>return</code> statement that returns an array containing the names of the attributes you want to observe:</p>
+
+<pre class="brush: js">static get observedAttributes() {return ['w', 'l']; }</pre>
+
+<p>This is placed right at the top of the constructor, in our example.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Find the <a href="https://github.com/mdn/web-components-examples/blob/master/life-cycle-callbacks/main.js">full JavaScript source</a> here.</p>
+</div>