I have a custom element my-checkbox
that wraps a checkbox, label, styling, etc. When that checkbox is toggled I am defining a CustomEvent
named check within my constructor, like so:
constructor(){
super();
this._shadowRoot = this.attachShadow({mode: 'open'});
this.checkEvent = new CustomEvent("check", {
bubbles: true,
cancelable: false,
});
}
I dispatch that event when the checkbox is toggled:
toggleCheckbox(){
this.dispatchEvent(this.checkEvent);
console.log(this.checkEvent);
...
}
I infer that this event is being dispatched because the contents of the console.log show the signature of a CustomEvent
I have another custom element my-checkreport
that contains my-checkbox and is supposed to react to the "check" event. I have defined an event listener in the connected callback of my-checkreport
connectedCallback(){
...
this.addEventListener("check", function (e) {
console.log('listend to check event');
console.log(e);
});
}
However, this eventListener never fires, never seems to 'hear' the "check" event dispatched in the my-checkbox
component. I've tried adding this listener in the constructor with the same result.
Any ideas what I'm doing wrong?
Background: I'm doing it this way in the interest of making these elements composable. I also have read that best practices for developing web components is to "Use custom events to pass information out of components..."
To listen for the custom event, add an event listener to the element you want to listen on, just as you would with native DOM events. document. querySelector("#someElement"). addEventListener("myevent", (event) => { console.
The addEventListener() method allows you to add event listeners on any HTML DOM object such as HTML elements, the HTML document, the window object, or other objects that support events, like the xmlHttpRequest object.
js function subscribe(eventName, listener) { document. addEventListener(eventName, listener); } function unsubscribe(eventName, listener) { document. removeEventListener(eventName, listener); } function publish(eventName, data) { const event = new CustomEvent(eventName, { detail: data }); document.
The addEventListener() is an inbuilt function in JavaScript which takes the event to listen for, and a second argument to be called whenever the described event gets fired. Any number of event handlers can be added to a single element without overwriting existing event handlers.
For others who end up here, the specific property you're looking for to break out of the shadow root 'jail' is "composed".
So:
this.checkEvent = new CustomEvent("check", {
bubbles: true,
cancelable: false,
composed: true
});
You can also add another property, "detail" which will carry custom data on the event, if you like.
More info here: composed property
If your compound element <my-checkreport>
uses a Shadow DOM to embed its content (<my-checkbox>
, label, styling...), dispatched events from an inner element (here <my-checkbox>
) will be fired inside the (container's) Shadow DOM.
Therefore, you should add the event listener to the Shadow DOM's root of the compound custom element (this.shadowRoot
) instead of to the element (this
) itself. In <my-checkreport>
:
connectedCallback(){
...
this.shadowRoot.addEventListener("check", function (e) {
console.log('listend to check event');
console.log(e);
});
}
More on Shadow DOM:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With