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:33] alfred [Slots] |
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 130: | 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> | ||