UNPKG

joicomponents

Version:

Design patterns to build native web components

93 lines (86 loc) 2.81 kB
<script> function log(e){ console.log(this.tagName, e.target.tagName + "#" + e.target.id); } class GrandFather extends HTMLElement { constructor(){ super(); this.attachShadow({mode: "open"}); this.shadowRoot.innerHTML = "<the-father><slot id='grandFather'></slot></the-father>"; this.shadowRoot.addEventListener("slotchange", log.bind(this)); } } class TheFather extends HTMLElement { constructor(){ super(); this.attachShadow({mode: "open"}); this.shadowRoot.innerHTML = "<the-child><slot id='father'></slot></the-child>"; this.shadowRoot.addEventListener("slotchange", log.bind(this)); } } class TheChild extends HTMLElement { constructor(){ super(); this.attachShadow({mode: "open"}); this.shadowRoot.innerHTML = "<slot id='child'></slot>"; this.shadowRoot.addEventListener("slotchange", log.bind(this)); } } customElements.define("grand-father", GrandFather); customElements.define("the-father", TheFather); customElements.define("the-child", TheChild); </script> <grand-father>matroska</grand-father> <h3>Explanation: </h3> The flattened DOM looks like this: <pre> ... < grand-father > #shadowRoot < the-father > #shadowRoot < the-child > #shadowRoot < slot#child > < slot#father > < slot#grandFather > matroska </pre> Constructing this DOM produces six logs: <pre> THE-CHILD SLOT#father THE-FATHER SLOT#father THE-CHILD SLOT#child THE-CHILD SLOT#grandFather THE-FATHER SLOT#grandFather GRAND-FATHER SLOT#grandFather </pre> <ol> <li> Log 1 and 2 are the same slotchange event, ie. slot#grandFather being transposed to slot#father. </li> <li> Log 3 is the innermost slotchange event, ie. slot#father being transposed to slot#child. </li> <li> Log 4, 5, and 6 is the final slotchange event, ie. "matroska" being transposed to slot#grandFather. </li> <li> The slotchange listener are triggered: 3 x the-child, 2 x the-father, 1 x grand-father. the-child web component has principally no way of knowing how many times its slotchange listener will be triggered during construction. </li> </ol> <pre> ... < grand-father > _ #shadowRoot *6 < the-father > _ | #shadowRoot *2 *5 < the-child > | _ | #shadowRoot *1 *3 *4 < slot#child > | ^ | < slot#father > ^ | < slot#grandFather > ^ matroska </pre>