Search code examples
javascripthtmlweb-componentshadow-dom

How to listen to events that got fired in shadow dom of child element?


I have two web-components, one is something like a list-item and the other one is the container. In the list item there is a button, which dispatches an event onclick. Both components use separated shadow-doms.

<custom-list>
        <custom-list-item></custom-list-item>
        <custom-list-item></custom-list-item>
        <custom-list-item></custom-list-item>
</custom-list>

How can I listen in 'custom-list' to the event that gets emitted by the button in 'custom-list-item'?


Solution

  • In the container custom element <custom-list>, simply listen to the click element on the Shadow DOM root. The click event emitted by the element in the inner Shadow DOM will naturally bubble to its container.

    this.shadowRoot.addEventListener( 'click', ev => console.log( ev.target.id ) )
    

    You can also implement the handleEvent() method to process all the events managed inside your custom element:

    customElements.define( 'custom-list-item', class extends HTMLElement {
        constructor() {
            super()
            this.attachShadow( { mode: 'open' } )
                .innerHTML = `<button>Click</button>`             
        }  
    } )
    
    customElements.define( 'custom-list', class extends HTMLElement {
        constructor() {
            super() 
            this.attachShadow( { mode: 'open' } )
                .innerHTML = `
                    <custom-list-item id=1></custom-list-item>
                    <custom-list-item id=2></custom-list-item>
                    <custom-list-item id=3></custom-list-item>` 
            this.shadowRoot.addEventListener( 'click', this )
        }
        handleEvent( ev ) {
            console.log( ev.target.id )
        }
    } )
    <custom-list></custom-list>