Search code examples
javascriptcssshadow-dom

Check if element contains #shadow-root


Is it possible to see if a Shadow DOM element exists? I'm not too concerned with manipulating it, or even really targeting it per-say. I understand the reasoning of the encapsulation. But I'd like to be able to style other elements in the regular DOM, based on whether or not the Shadow DOM element is present.

Sort of like:

if ( $('#element-id #shadow-root').length ) {
    // true
}

Or if not for the shadow-root, at least a specific element within, like the id of a div. So if that div exists, then clearly that Shadow DOM element is on the page.

I know it wouldn't be that simple... From some research I've done, there are things like >>> and /deep/ but their support seems to be low/none/deprecated. Buy maybe there's another way, however inelegant it may be?


Solution

  • If you want to check whether or not a specific element is hosting an open Shadow DOM element, you can do the following:

    var el = document.querySelector('#some-element');
    if (!!el.shadowRoot) {
        // Then it is hosting an OPEN Shadow DOM element
    }
    

    You can also get the Shadow DOM element, and then operate on it like a normal node:

    var shadowEl = el.shadowRoot;
    // And for example:
    console.log(shadowEl.innerHTML);
    

    Here is an example that works in the latest version of Chrome:

    const div = document.querySelector('div');
    const p = document.querySelector('p');
    
    const shadowRoot = p.attachShadow({mode: 'open'})
    shadowRoot.textContent = 'A Shadow DOM Paragraph. I overrode the content specified!';
    
    console.log('Paragraph has Shadow DOM:', !!p.shadowRoot); // true
    console.log('Div has Shadow DOM:', !!div.shadowRoot); // false
    <div>A Normal Div</div>
    <p>A Normal Paragraph</p>