|  |  |  | 
|---|
|  |  |  | </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 = ` | 
|---|
|  |  |  | 
|---|
|  |  |  | <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="js" data-trim data-line-numbers="2|8-10"> | 
|---|
|  |  |  | 
|---|
|  |  |  | class HelloWorldComponent extends HTMLElement { | 
|---|
|  |  |  | static observedAttributes = ["my-attribute"]; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | connectedCallback() { | 
|---|
|  |  |  | constructor() { | 
|---|
|  |  |  | // ... | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | <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> | 
|---|
|  |  |  | </div> | 
|---|
|  |  |  | </div> | 
|---|