From 0ce1abf05619d2f2121157ebe03ec17b7fb6bdc4 Mon Sep 17 00:00:00 2001 From: Sascha Schulz <sschulz@dh-software.de> Date: Mo, 05 Feb 2024 12:59:03 +0100 Subject: [PATCH] add slots and introduction to styling --- index.html | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 161 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index e2e7f58..ab3d7d5 100644 --- a/index.html +++ b/index.html @@ -3554,10 +3554,12 @@ </section> <section> <pre> - <code class="js" data-trim data-line-numbers="1-15|17"> + <code class="js" data-trim data-line-numbers="1-16|19"> <script type="text/template"> class HelloWorldComponent extends HTMLElement { - connectedCallback() { + constructor() { + super(); + const shadowRoot = this.attachShadow({mode: "open"}); shadowRoot.innerHTML = ` @@ -3581,14 +3583,44 @@ <iframe data-src="/assets/html/hello-world.html"></iframe> </section> <section> + <h4>Light DOM vs Shadow DOM</h4> + <img data-src="/assets/images/web-components-shadow-root.png" width="500px"> + </section> + <section> + <h4>Suche von Elementen im Light- und Shadow DOM</h4> + <pre> + <code class="js" data-trim data-line-numbers> + <script type="text/template"> + // Light DOM + const span = document.querySelector("span"); // Hi! + const divs = document.querySelectorAll("div"); + + console.log(divs.length); // => 1 + + // Shadow DOM + const helloWorld = document.querySelector("hello-world"); + + helloWorld.shadowRoot.querySelector("div"); // Hello World! + </script> + </code> + </pre> + </section> + <section> <h3>Auf Attribute reagieren</h3> + <pre> + <code class="html" data-trim data-line-numbers> + <script type="text/template"> + <hello-world my-attribute="a"></hello-world> + </script> + </code> + </pre> <pre> <code class="js" data-trim data-line-numbers="2|8-10"> <script type="text/template"> class HelloWorldComponent extends HTMLElement { static observedAttributes = ["my-attribute"]; - connectedCallback() { + constructor() { // ... } @@ -3605,6 +3637,132 @@ <p>Lasse die eigene Komponente "hello-sayer" auf eine Änderung des "name"-Attributs reagieren, indem der dort eingetragene Name in der Komponente angezeigt wird (Beispiel: name="Joe" => Hello Joe!)</p> <p>(/examples/templates/web-components/hello-sayer.html)</p> </section> + <section> + <h3>Musterlösung</h3> + <pre> + <code class="js" data-trim data-line-numbers> + <script type="text/template"> + class HelloSayerComponent extends HTMLElement { + static observedAttributes = ["name"]; + + constructor() { + super(); + + this.root = this.attachShadow({mode: "open"}); + + this.root.innerHTML = ` + <style> + div { + background-color: coral; + color: white; + } + </style> + <div>Hello!</div> + `; + } + + attributeChangedCallback(name, oldValue, newValue) { + this.root.querySelector("div").innerHTML = `Hello ${newValue}!`; + } + } + + window.customElements.define("hello-sayer", HelloSayerComponent); + + const names = ["Joe", "Allie"]; + let counter = 0; + + setInterval(() => document.querySelector("hello-sayer").setAttribute("name", names[counter++ % 2]), 2000); + </script> + </code> + </pre> + </section> + <section> + <iframe data-src="/assets/html/hello-sayer.html"></iframe> + </section> + <section> + <h3>Elemente aus dem LightDOM platzieren mit <code><slot></code></h3> + <pre> + <code class="js" data-trim data-line-numbers> + <script type="text/template"> + this.root.innerHTML = ` + <span>Hello <slot></slot>!</span> + `; + </script> + </code> + </pre> + </section> + <section> + <h4>Beispiel</h4> + <pre> + <code class="html" data-trim data-line-numbers> + <script type="text/template"> + <hello-sayer>Joe</hello-sayer> + <hello-sayer>Allie</hello-sayer> + </script> + </code> + </pre> + <iframe data-src="/assets/html/hello-sayer-2.html"></iframe> + </section> + <section> + <h3>Mehrfache benannte <code><slot></code>s</h3> + <pre> + <code class=js data-trim data-line-numbers> + <script type="text/template"> + this.root.innerHTML = ` + <span> + first name: <slot name="first"></slot> | + last name: <slot name="last"></slot> + </span> + `; + </script> + </code> + </pre> + </section> + <section> + <h4>Beispiel</h4> + <pre> + <code class="html" data-trim data-line-numbers> + <script type="text/template"> + <name-field> + <span slot="first">Leia</span> + <span slot="last">Organa</span> + </name-field> + </script> + </code> + </pre> + <iframe data-src="/assets/html/name-field.html"></iframe> + </section> + <section> + <h3>Aufgabe</h3> + <p>Entwerfe eine <code>CardComponent</code> (Vorlage "card-component.html") in folgendem Stil und nutze dabei sinnvolle <code><slot></code>s:</p> + <pre> + <code class="html" data-trim data-line-numbers> + <script type="text/template"> + <card-component> + <span slot="title">This is a title</span> + <span slot="content">...Lorem ipsum dolor sit amet, consetetur sadipscing elitr...</span> + </card-component> + </script> + </code> + </pre> + <iframe data-src="/assets/html/exercise-card-component.html"></iframe> + </section> + <section> + <h3>Styling einer Web Component</h3> + <pre> + <code class="css" data-trim data-line-numbers> + <script type="text/template"> + :host { + display: block; /* inline, inline-block, flex, grid etc... */ + + color: red; + + font-family: Arial, Helvetica, sans-serif; + } + </script> + </code> + </pre> + </section> </section> </div> </div> -- Gitblit v1.9.3