The documentation on MDN highlights the presence of a method within the event
object called composedPath. This method stores an array of objects where listeners will be triggered, excluding nodes in shadow trees if the shadow root was created with its ShadowRoot.mode set to closed.
While this functionality appears to function correctly in Chrome, the extent of support for this method across different browsers is not clearly outlined in the documentation.
Further examination of the event
object unveiled the existence of a property named event.path
, which holds the same path array – at least in Chrome. Strangely, no information can be found regarding event.path
in any documented source.
In light of this ambiguity, some sources recommend using
var eventPath = event.path || (event.composedPath &&
event.composedPath());
instead of solely relying on var eventPath =
event.composedPath();
.
If your browser does indeed support it, you have the option to traverse through the path of the clicked element and verify whether it is a child of a button or the button itself.
The following code snippet exemplifies this procedure and retains a reference to the button element for future usage:
document.getElementById('wrapper').addEventListener('click', function() {
// actual element clicked
console.log(event.target);
var buttonClicked = false;
var button;
var eventPath = event.composedPath();
for (let i = 0; i < eventPath.length; i++) {
if (eventPath[i].tagName && eventPath[i].tagName.toLowerCase() === 'button') {
buttonClicked = true;
button = eventPath[i];
break;
}
}
if (buttonClicked) {
console.log(button);
console.log('button was clicked');
}
})
<div id="wrapper">
<button class="c-config__option c-config__option--button c-config__option--pack" data-index="0">
Item 1
<span>Subtext</span>
</button>
<button class="c-config__option c-config__option--button c-config__option--pack" data-index="1">
Item 2
<span>Subtext</span>
</button>
</div>
An alternative approach involves replicating jQuery.closest by utilizing the solution presented in this Stack Overflow post: DOM / pure JavaScript solution to jQuery.closest() implementation?