Zum Inhalt springen

Webkomponenten

Webkomponenten sind ein leistungsstarkes Werkzeug in der modernen Webentwicklung, das es Entwicklern ermöglicht, wiederverwendbare, gekapselte HTML-Elemente zu erstellen. In diesem Leitfaden tauchen wir tief in die Welt der Webkomponenten ein und bieten umfangreiche Codebeispiele sowie detaillierte Erklärungen, um Ihnen zu helfen, diesen wesentlichen Aspekt von JavaScript zu meistern.

Einführung in Webkomponenten

Webkomponenten sind eine Reihe von Web-Plattform-APIs, mit denen Sie neue, benutzerdefinierte, wiederverwendbare und gekapselte HTML-Tags erstellen können, die sich in Webseiten und Web-Apps verwenden lassen. Die primären Technologien, die in Webkomponenten verwendet werden, sind Custom Elements, Shadow DOM und HTML Templates.

Custom Elements

Custom Elements definieren neue HTML-Tags und ihr Verhalten. Diese Elemente können wie jedes Standard-HTML-Tag verwendet werden, jedoch mit benutzerdefiniertem Verhalten und Stil.


html
<div>
  <script>
    class MyElement extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.shadowRoot.innerHTML = '<p>Hello, World!</p>';
      }
    }
    customElements.define('my-element', MyElement);
  </script>
  <my-element></my-element>
</div>

Dieses Code-Snippet zeigt, wie man ein benutzerdefiniertes HTML-Element namens my-element erstellt. Die Klasse MyElement erweitert HTMLElement, hängt ein Shadow DOM an, um den Inhalt zu kapseln, und fügt ein einfaches Absatz-Element mit dem Text „Hello, World!“ ein.

Shadow DOM

Shadow DOM bietet Kapselung für Ihre benutzerdefinierten Elemente. Es ermöglicht Ihnen, Stile und Skripte auf das Element selbst zu beschränken.


html
<div>
  <script>
    class ShadowElement extends HTMLElement {
      constructor() {
        super();
        let shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = `
          <style>
            p { color: blue; }
          </style>
          <p>Shadow DOM content</p>
        `;
      }
    }
    customElements.define('shadow-element', ShadowElement);
  </script>
  <shadow-element></shadow-element>
</div>

In diesem Beispiel erweitert die Klasse ShadowElement HTMLElement und hängt einen Shadow Root an das Element an. Der Parameter mode: 'open' gibt an, dass das Shadow DOM über JavaScript zugänglich ist. Wenn mode auf 'open' gesetzt ist, kann der Shadow Root über die Eigenschaft element.shadowRoot abgerufen werden. Wenn mode auf 'closed' gesetzt ist, ist der Shadow Root von außen nicht zugänglich, was die Kapselung verbessert und verhindert, dass externe Skripte direkt auf das Shadow DOM zugreifen.

Innerhalb des Shadow DOMs definieren wir einige Stile und HTML-Inhalte. Die Stile (in diesem Fall ein Absatz mit blauem Text) sind auf das Shadow DOM beschränkt, sodass sie keine anderen Elemente auf der Seite beeinflussen. Diese Kapselung ist vorteilhaft für die Erstellung wiederverwendbarer Komponenten mit konsistentem Styling und Verhalten, unabhängig vom Kontext, in dem sie verwendet werden.

WARNING

Verwenden Sie lokale Stile innerhalb des Shadow DOMs, um Style-Leckagen zu verhindern und sicherzustellen, dass die Komponentestile gekapselt sind.

HTML Templates

HTML Templates ermöglichen es Ihnen, wiederverwendbare HTML-Blöcke zu definieren, die zur Laufzeit instanziiert werden können.


html
<div>
  <template id="my-template">
    <style>
      p { color: red; }
    </style>
    <p>This is a template content</p>
  </template>
  <script>
    const template = document.getElementById('my-template').content;
    document.body.appendChild(template.cloneNode(true));
  </script>
</div>

Dieses Beispiel zeigt, wie HTML Templates verwendet werden. Das <template>-Tag enthält HTML und Stile, die nicht sofort gerendert werden. Das Skript klont den Inhalt des Templates und hängt ihn an den Dokumentkörper an, wodurch er sichtbar wird.

Erstellen Ihrer ersten Webkomponente

Gehen wir gemeinsam durch den Prozess der Erstellung einer voll funktionsfähigen Webkomponente, die in verschiedenen Projekten verwendet werden kann.

Schritt 1: Komponente definieren

Erstellen Sie eine neue Klasse, die HTMLElement erweitert.


html
<div>
  <script>
    class MyComponent extends HTMLElement {
      constructor() {
        super();
        const shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = 'Hello, World!'
      }
    }
    customElements.define('my-component', MyComponent);
  </script>
  <my-component></my-component>
</div>

Dieses Snippet legt das Fundament für eine Webkomponente namens my-component. Es definiert eine Klasse, die HTMLElement erweitert, und hängt ein Shadow DOM an, um sie für weitere Anpassungen vorzubereiten.

Schritt 2: Stile und Templates hinzufügen

Verwenden Sie das Shadow DOM, um Stile und Templates zu kapseln.


html
<div>
  <script>
    class MyStyledComponent extends HTMLElement {
      constructor() {
        super();
        let shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = `
          <style>
            p { font-size: 20px; color: green; }
          </style>
          <p>This is my styled component!</p>
        `;
      }
    }
    customElements.define('my-styled-component', MyStyledComponent);
  </script>
  <my-styled-component></my-styled-component>
</div>

Dieses Snippet verbessert my-styled-component, indem es gekapselte Stile innerhalb des Shadow DOMs hinzufügt. Der Absatz innerhalb der Komponente wird mit grüner Farbe und einer erhöhten Schriftgröße gestaltet.

Schritt 3: Interaktivität hinzufügen

Fügen Sie JavaScript hinzu, um Ihre Komponente interaktiv zu machen.


html
<div>
  <script>
    class InteractiveComponent extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.shadowRoot.innerHTML = `
          <style>
            p { font-size: 20px; }
          </style>
          <p>This is interactive!</p>
          <button>Click me</button>
        `;
        this.shadowRoot.querySelector('button').addEventListener('click', () => {
          this.shadowRoot.querySelector('p').textContent = 'You clicked!';
        });
      }
    }
    customElements.define('interactive-component', InteractiveComponent);
  </script>
  <interactive-component></interactive-component>
</div>

Dieses Beispiel zeigt, wie man eine Webkomponente interaktiv macht. Die InteractiveComponent enthält eine Schaltfläche, die beim Klicken den Textinhalt eines Absatzes innerhalb der Komponente ändert.

Fortgeschrittene Techniken für Webkomponenten

Lifecycle Callbacks

Custom Elements verfügen über Lifecycle Callbacks, mit denen Sie Code während bestimmter Phasen im Leben eines Elements ausführen können.


html
<div>
  <script>
    class LifecycleComponent extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
      }
      connectedCallback() {
        this.shadowRoot.innerHTML = '<p>Element added to page.</p>';
      }
      disconnectedCallback() {
        console.log('Element removed from page.');
      }
    }
    customElements.define('lifecycle-component', LifecycleComponent);
  </script>
  <lifecycle-component></lifecycle-component>
</div>

Dieses Snippet demonstriert die Verwendung von Lifecycle Callbacks in Webkomponenten. Der LifecycleComponent aktualisiert seinen Inhalt, wenn er zur Seite hinzugefügt wird, und protokolliert eine Nachricht, wenn er entfernt wird.

Behandlung von Attributänderungen

Reagieren Sie auf Änderungen an den Attributen eines Elements, indem Sie das Array observedAttributes definieren und die Methode attributeChangedCallback implementieren.


html
<div>
  <script>
    class AttributeComponent extends HTMLElement {
      static get observedAttributes() {
        return ['data-text'];
      }
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.shadowRoot.innerHTML = '<p></p>';
      }
      attributeChangedCallback(name, oldValue, newValue) {
        if (name === 'data-text') {
          this.shadowRoot.querySelector('p').textContent = newValue;
        }
      }
    }
    customElements.define('attribute-component', AttributeComponent);
  </script>
  <attribute-component data-text="Initial text"></attribute-component>
  <script>
    const element = document.querySelector('attribute-component');
    setTimeout(() => {
      element.setAttribute('data-text', 'Updated text');
    }, 2000);
  </script>
</div>

Dieses Beispiel zeigt, wie Attributänderungen in einer Webkomponente behandelt werden. Der AttributeComponent aktualisiert seinen internen Inhalt basierend auf Änderungen am data-text-Attribut.

Best Practices für Webkomponenten

Shadow DOM sinnvoll nutzen

Kapseln Sie Stile und Skripte innerhalb des Shadow DOMs, um Konflikte mit anderen Elementen auf der Seite zu verhindern.

Namenskonventionen einhalten

Custom Elements müssen einen Bindestrich in ihrem Namen enthalten, um Konflikte mit Standard-HTML-Elementen zu vermeiden.

Komponenten modular halten

Erstellen Sie kleine, wiederverwendbare Komponenten, um Ihren Code wartbar und skalierbar zu halten.

Globale Stile vermeiden

Verwenden Sie lokale Stile innerhalb des Shadow DOMs, um Style-Leckagen zu verhindern und sicherzustellen, dass die Komponentestile gekapselt sind.

Dokumentation und Tests

Dokumentieren Sie Ihre Komponenten gut und schreiben Sie Tests, um sicherzustellen, dass sie in verschiedenen Browsern und Anwendungsfällen wie erwartet funktionieren.

Fazit

Webkomponenten sind eine vielseitige und leistungsstarke Funktion in der modernen Webentwicklung, die die Erstellung wiederverwendbarer, gekapselter benutzerdefinierter Elemente ermöglicht. Durch das Verständnis und die Nutzung von Custom Elements, Shadow DOM und HTML Templates können Sie modulare, wartbare und skalierbare Webanwendungen erstellen. Dieser Leitfaden hat Ihnen das Wissen und die Beispiele an die Hand gegeben, die Sie benötigen, um mit Webkomponenten zu beginnen, und stellt sicher, dass Sie sie effektiv in Ihren Projekten implementieren können.

Praxis

Welche der folgenden Aussagen über Webkomponenten ist korrekt?

Finden Sie das nützlich?

Dual-run-Vorschau — vergleichen Sie mit den Symfony-Routen live.