| | |
| | | </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> |