Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
wiki2:webcomponents [2020/06/01 10:19] alfred [CSS] |
wiki2:webcomponents [2021/05/08 07:32] (actual) |
||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| ====== Web Components ====== | ====== Web Components ====== | ||
| + | |||
| + | **Libraries**: | ||
| + | |||
| + | * [[wiki2:webcomponents:ficusjs]] | ||
| + | |||
| ===== Basic ===== | ===== Basic ===== | ||
| Línea 63: | Línea 68: | ||
| ==== Shadow DOM ==== | ==== Shadow DOM ==== | ||
| + | Shadow DOM allows hidden DOM trees to be attached to elements in the regular DOM tree. | ||
| + | |||
| + | * Shadow host: The regular DOM node that the shadow DOM is attached to. | ||
| + | * Shadow tree: The DOM tree inside the shadow DOM. | ||
| + | * Shadow boundary: the place where the shadow DOM ends, and the regular DOM begins. | ||
| + | * Shadow root: The root node of the shadow tree. | ||
| + | |||
| + | You can attach a shadow root to any element using the ''Element.attachShadow()'' method. This takes as its parameter an options object that contains one option — mode — with a value of open or closed: | ||
| + | <code javascript> | ||
| + | let shadow = elementRef.attachShadow({mode: 'open'}); | ||
| + | let shadow = elementRef.attachShadow({mode: 'closed'}); | ||
| + | </code> | ||
| + | ''open'' means that you can access the shadow DOM using JavaScript written in the main page context, for example using the Element.shadowRoot property: | ||
| + | <code javascript> | ||
| + | let myShadowDom = myCustomElem.shadowRoot; | ||
| + | </code> | ||
| + | If you attach a shadow root to a custom element with mode: ''closed'' set, you won't be able to access the shadow DOM from the outside — ''myCustomElem.shadowRoot'' returns null. This is the case with built in elements that contain shadow DOMs, such as ''<video>''. | ||
| ==== Templates ==== | ==== Templates ==== | ||
| Instead of defining the HTML and CSS in a JavaScript string, you can use a template tag in HTML and assign it an id: | Instead of defining the HTML and CSS in a JavaScript string, you can use a template tag in HTML and assign it an id: | ||
| Línea 95: | Línea 117: | ||
| ==== Slots ==== | ==== Slots ==== | ||
| + | Slots are identified by their name attribute, and allow you to define placeholders in your template that can be filled with any markup fragment you want when the element is used in the markup. | ||
| + | We would define a slot: | ||
| + | <code html> | ||
| + | <p><slot name="my-text">My default text</slot></p> | ||
| + | </code> | ||
| + | |||
| + | Then, inside your web-component: | ||
| + | |||
| + | <code html> | ||
| + | <my-paragraph> | ||
| + | <span slot="my-text">Let's have some different text!</span> | ||
| + | </my-paragraph> | ||
| + | <!-- or --> | ||
| + | <my-paragraph> | ||
| + | <ul slot="my-text"> | ||
| + | <li>Let's have some different text!</li> | ||
| + | <li>In a list!</li> | ||
| + | </ul> | ||
| + | </my-paragraph> | ||
| + | </code> | ||
| ==== CSS ==== | ==== CSS ==== | ||
| Línea 103: | Línea 145: | ||
| * '':host:'' - Selects the shadow host of the shadow DOM containing the CSS it is used inside. | * '':host:'' - Selects the shadow host of the shadow DOM containing the CSS it is used inside. | ||
| * '':host():'' - Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host. | * '':host():'' - Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host. | ||
| - | * :host-context():'' - Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host's ancestor(s) in the place it sits inside the DOM hierarchy. | + | * '':host-context():'' - Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host's ancestor(s) in the place it sits inside the DOM hierarchy. |
| === CSS pseudo-elements === | === CSS pseudo-elements === | ||
| Línea 110: | Línea 152: | ||
| + | ===== How to... ===== | ||
| + | ==== ... define inline template? ==== | ||
| + | <code> | ||
| + | var template = document.createRange().createContextualFragment( ` | ||
| + | <style> | ||
| + | div {font-family: "Open Sans Light",Helvetica,Arial} | ||
| + | <div> | ||
| + | <slot name="attributes"></slot> | ||
| + | </div> | ||
| + | <hr> | ||
| + | `); | ||
| + | const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(template.cloneNode(true)); | ||
| + | </code> | ||
| + | |||
| + | ==== ... treat slots inner content? ==== | ||
| + | <code> | ||
| + | <custom-menu id="menu"> | ||
| + | <span slot="title">Candy menu</span> | ||
| + | <li slot="item">Lollipop</li> | ||
| + | <li slot="item">Fruit Toast</li> | ||
| + | </custom-menu> | ||
| + | |||
| + | <script> | ||
| + | customElements.define('custom-menu', class extends HTMLElement { | ||
| + | items = [] | ||
| + | |||
| + | connectedCallback() { | ||
| + | this.attachShadow({mode: 'open'}); | ||
| + | this.shadowRoot.innerHTML = `<div class="menu"> | ||
| + | <slot name="title"></slot> | ||
| + | <ul><slot name="item"></slot></ul> | ||
| + | </div>`; | ||
| + | |||
| + | // slottable is added/removed/replaced | ||
| + | this.shadowRoot.firstElementChild.addEventListener('slotchange', e => { | ||
| + | let slot = e.target; | ||
| + | if (slot.name == 'item') { | ||
| + | this.items = slot.assignedElements().map(elem => elem.textContent); | ||
| + | alert("Items: " + this.items); | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | // items update after 1 second | ||
| + | setTimeout(() => { | ||
| + | menu.insertAdjacentHTML('beforeEnd', '<li slot="item">Cup Cake</li>') | ||
| + | }, 1000); | ||
| + | </script> | ||
| + | </code> | ||