Hi, we have shadow DOM elements (#shadow-root (open) ) on the site and I have observed that the "click" event type doesn't work in the listener (using plain javaScript). However, substituting it with a "mouseup" event produces the relevant outcome. Namely, I am talking about our custom activity map implementation. Has anyone come across this before? Thanks.
解決済! 解決策の投稿を見る。
表示
返信
いいね!の合計
Hi @Franc_G
You’re definitely not alone in running into this. Shadow DOM introduces some quirks when it comes to event handling, and the click event is one of the trickier ones because of how event retargeting and encapsulation work.
If mouseup is working and click isn’t, it likely comes down to how the Shadow DOM manages event bubbling. click doesn't always bubble through the shadow boundary the way you'd expect, whereas moueup tends to behave more reliably in that regard, especially with custom listeners or tracking layers like Activity Map.
You can do the following -
If you control the component, make sure any custom events are fired with composed: true and bubbles: true so they can cross the shadow boundary.
If you're just listening from outside and can't modify the component, then sticking with mouseup is a perfectly valid workaround and quite common in shadow-heavy apps.
Also worth checking if the component has a click handler that’s stopping propagation. That would explain why your external listener never fires on click, but mouseup sneaks through.
Your current fix using mouseup is solid, and unless you can tweak the component’s internals, it might be the best route.
Hope it works!
Hey @Franc_G
and your event listener is custom and not a built-in click event?
Could it be that the click is not bubbling and captured by the element itself i .e., in the component's custom click handler?
That could explain why the mouseup still works if the event propagation is working there.
I would reach out to a developer about that and ask him if they explicitly stop event bubbling / propagation
Hi @Franc_G ,
Yes, this is a known behavior. When working with Shadow DOM elements, the "click" event often doesn’t work as expected in external event listeners due to event retargeting and the encapsulation that Shadow DOM enforces. In many cases, "mouseup" propagates more reliably across shadow boundaries, which is why you might see it working better especially in custom implementations like Activity Map.
Some recommendations:
Use mouseup for Shadow DOM elements:
If it works and suits your tracking goals, it's a valid and simple workaround.
Delegate Listener inside Shadow DOM
If you have access to the shadow root:
shadowRoot.querySelector('button').addEventListener('click', function(e) {
// track click
});
Hi @Franc_G
You’re definitely not alone in running into this. Shadow DOM introduces some quirks when it comes to event handling, and the click event is one of the trickier ones because of how event retargeting and encapsulation work.
If mouseup is working and click isn’t, it likely comes down to how the Shadow DOM manages event bubbling. click doesn't always bubble through the shadow boundary the way you'd expect, whereas moueup tends to behave more reliably in that regard, especially with custom listeners or tracking layers like Activity Map.
You can do the following -
If you control the component, make sure any custom events are fired with composed: true and bubbles: true so they can cross the shadow boundary.
If you're just listening from outside and can't modify the component, then sticking with mouseup is a perfectly valid workaround and quite common in shadow-heavy apps.
Also worth checking if the component has a click handler that’s stopping propagation. That would explain why your external listener never fires on click, but mouseup sneaks through.
Your current fix using mouseup is solid, and unless you can tweak the component’s internals, it might be the best route.
Hope it works!
@bjoern__koth @pradnya_balvir @Vinay_Chauhan
Thank you for the suggestions—exactly what I needed! I was, and still am, a bit hesitant to change the event type from "click" to "mouseup" in the custom activity map, but you’ve given me all the information I need. Much appreciated.
Additionally, I’ve discovered an easy way to test whether this issue is related to event bubbling (see below).
By tweaking the options parameter in the listener, we can quickly determine whether the event type bubbles or not.
Event propagation in JavaScript consists of three phases:
By default, most event listeners in JavaScript respond during the bubbling phase, but you can also configure them to respond during the capturing phase.
document.addEventListener('click', function () { console.log('Capturing phase'); }, true); // Capturing phase document.addEventListener('click', function () { console.log('Bubbling phase'); }, false); // Bubbling phase (default)
Upon multiple interactions with the shadow DOM element I get the following log.
@bjoern__koth @pradnya_balvir @Vinay_Chauhan
Does anyone have an opinion on which one is better?
document.addEventListener('click', function () {
console.log('Capturing phase');
}, true); // Capturing phase
OR
document.addEventListener('mouseup', function () {
console.log('Capturing phase');
}); // "mouseup" event type;
I know it’s pretty much the same thing, but nevertheless, I’m talking specifically about the activity map custom implementation.
表示
返信
いいね!の合計
I am not sure what is the safest, however, you might want to also run a test using mobile devices? Like test with a real android and iOS (or multiple) devices to ensure the listener works for them too....
I feel like click might work better on mobile devices.. but that's a guess.....
Or you might have to create separate listeners for mobile devices that look for the touchend (equivalent to mouseup) or touchstart (equivalent to mousedown) events... since there is definitely no "mouse" events on a phone or tablet (well.... in most cases... I'm sure there is some person out there with a mouse on their tablet....)
@Jennifer_Dungan it is a good point, thank you. I did some testing in the console using mobile type devices provided (iPhone and android), but will try to experiment with an actual mobile phone. Thanks once again.
表示
返信
いいね!の合計