Custom Element getRootNode.closest() function crossing multiple (parent) shadowDOM boundaries

This does the same as .closest() from inside any child (shadow)DOM

but walking up the DOM crossing shadowroot Boundaries

Optimized for (extreme) minification

//declared as method on a Custom Element:
closestElement(
    selector,      // selector like in .closest()
    base = this,   // extra functionality to skip a parent
    __Closest = (el, found = el && el.closest(selector)) => 
        !el || el === document || el === window
            ? null // standard .closest() returns null for non-found selectors also
            : found 
                ? found // found a selector INside this element
                : __Closest(el.getRootNode().host) // recursion!! break out to parent DOM
) {
    return __Closest(base);
}

Note: the __Closest function is declared as ‘parameter’ to avoid an extra let declaration… better for minification, and keeps your IDE from complaining

Called from inside a Custom Element:

<element-x>
//# shadow-root
    <element-y>
        <element-z>
        //# shadow-root
        let container = this.closestElement('element-x');
        </element-z>
    </element-y>
</element-x>

Leave a Comment