From 1838ab5ce4d049d6c113124b1969dfebc90b4163 Mon Sep 17 00:00:00 2001
From: Sascha Schulz <sschulz@dh-software.de>
Date: Mo, 10 Jun 2024 12:21:30 +0200
Subject: [PATCH] add solution for tab component event exercise
---
index.html | 94 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 86 insertions(+), 8 deletions(-)
diff --git a/index.html b/index.html
index c820332..72434b9 100644
--- a/index.html
+++ b/index.html
@@ -36,9 +36,16 @@
<ul>
<li>JavaScript</li>
<li>Responsive Design</li>
- <li>NodeJS</li>
<li>WebComponents / lit</li>
+ <li>NodeJS</li>
<li>Datenbank</li>
+ </ul>
+ </section>
+ <section>
+ <h3>Betrieb</h3>
+ <ul>
+ <li>Server einrichten</li>
+ <li>SSL- / TLS-Zertifikate</li>
</ul>
</section>
<section>
@@ -66,13 +73,6 @@
<li>Progressive Web Application</li>
<li>CEF / Electron</li>
<li>WebAssembly</li>
- </ul>
- </section>
- <section>
- <h3>Betrieb</h3>
- <ul>
- <li>Server einrichten</li>
- <li>SSL- / TLS-Zertifikate</li>
</ul>
</section>
<section>
@@ -3889,6 +3889,84 @@
<h3>Aufgabe</h3>
<p>Definiere mit dem Pseudo-Elemente-Selektor <code>::slotted()</code> Styles, sodass per <code>slot</code> eingefügte Elemente mit der Klasse <code>red</code> einen roten und Elemente mit der Klasse <code>blue</code> einen blauen Hintergrund haben. Die Schriftart soll jeweils weiß sein (Vorlage "slotted.html")</p>
</section>
+ <section>
+ <h3>Events in Web Components</h3>
+ <img data-src="/assets/images/web-components-event-bubbling-shadow-dom.png">
+ <ul>
+ <li>Events können an einer Web Component selbst oder innerhalb des Shadow Dom <code>dispatcht</code> werden</li>
+ <li>Das Shadow Root der Komponente stellt eine Art "gläserne Decke" dar</li>
+ <li>Standard-Events der UI wie <code>click</code> bubbeln durch das Shadow Dom nach oben durch</li>
+ <li>Ein <code>CustomEvent</code> muss entsprechend konfiguriert werden</li>
+ </ul>
+ </section>
+ <section>
+ <pre>
+ <code class="js" data-trim data-line-numbers>
+ button.dispatchEvent(new CustomEvent(
+ "tabactivated", // Name des Events, frei wählbar
+ {
+ detail: "any data", // beliebige Daten wie Strings, Zahlen, Booleans usw.
+ bubbles: true, // bestimmt, ob das Event durch alle Eltern nach oben steigt
+ cancelable: true, // Abbrechbar per event.preventDefault()
+ composed: true // durch eventuelle Shadow Root steigen, falls vorhanden.
+ }
+ ));
+ </code>
+ </pre>
+ </section>
+ <section>
+ <h3>Aufgabe</h3>
+ <p>Entwickle eine Tab-Komponente (Vorlage "tab-componenmt.html"), welche beim Click auf einen Registerreite / Tab ein Event feuert, welches die Außenwelt über das gerade aktivierte Tab (tab-id) informiert</p>
+ </section>
+ <section>
+ <h3>Lösung</h3>
+ <pre>
+ <code class="js" data-trim data-line-numbers>
+ this.root.innerHTML = `
+ <style>
+ ::slotted(div) {
+ display: none;
+ }
+
+ ::slotted(div.active) {
+ display: block;
+ }
+ </style>
+
+ <div><slot name="tab"></slot></div>
+ <div><slot name="content"></slot></div>
+ `;
+ </code>
+ </pre>
+ </section>
+ <section>
+ <pre>
+ <code class="js" data-trim data-line-numbers>
+ connectedCallback() {
+ const firstContent = this.querySelector("div");
+
+ firstContent.classList.add("active");
+
+ this.addEventListener("click", (e) => {
+ if (e.target.tagName === "SPAN" && e.target.hasAttribute("tab-id")) {
+ const oldContent = this.querySelector("div.active");
+ const newContent = this.querySelector(`[tab-id="${e.target.getAttribute("tab-id")}"]`);
+
+ oldContent.classList.remove("active");
+ newContent.classList.add("active");
+
+ this.dispatchEvent(new CustomEvent("tabclick", {composed: true, bubbles: true, detail: e.target.getAttribute("tab-id"), cancelable: true}));
+ }
+ });
+ }
+ </code>
+ </pre>
+ </section>
+ </section>
+ <section>
+ <section>
+
+ </section>
</section>
</div>
</div>
--
Gitblit v1.9.3