So I have read several pieces that say if you want a custom event to traverse the shadow DOM boundary and cross into the light DOM you need to set the custom event's composed
property to true. I noticed however that any events I dispatch from a web component's this.
make it out of the shadowRoot component just fine, and ones that are dispatched from this.shadowRoot
stay inside. So why do I need the "composed" property? Am I doing something wrong?
const internalEvent = new CustomEvent("internalEvent", {bubbles: true, cancelable: false})
const externalEvent = new CustomEvent("externalEvent", {bubbles: true, cancelable: false})
class MyComponent extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = `
<button id="internalButton">INTERNAL</button>
<button id="externalButton">EXTERNAL</button>
`
this.internalButton = this.shadowRoot.getElementById("internalButton")
this.externalButton = this.shadowRoot.getElementById("externalButton")
}
connectedCallback() {
this.internalButton.addEventListener("click", ()=>{
this.shadowRoot.dispatchEvent(internalEvent)
})
this.externalButton.addEventListener("click", ()=>{
this.dispatchEvent(externalEvent)
})
this.shadowRoot.addEventListener("internalEvent", (event)=>{
console.log("Internal event detected internally.")
})
this.shadowRoot.addEventListener("externalEvent", (event)=>{
console.log("External event detected internally!")
})
}
}
document.addEventListener("internalEvent", ()=>console.log("Internal event detected externally!"))
document.addEventListener("externalEvent", ()=>console.log("External event detected externally."))
customElements.define('my-component', MyComponent)
edit: I'm just struggling to think of any reason where, to get a message to leave your component, you'd prefer to dispatch it within the shadowRoot and add a special property, rather than just dispatching it straight into the light DOM in the first place.