What is the shortest way possible to select a shadow root?

Some shadow roots are nested deep inside a wrapper, after many elements and often also after at least one cryptic element such as <ow-j3eolsu49kg>.

This situation may require doing something like this:

document.querySelector('.a').firstElementChild.firstElementChild.firstElementChild.shadowRoot.querySelector('.b').click();

Where firstElementChild there are cryptic elements.

Selecting the shadow root this way is cumbersome. Is there a more automatic way similar to in the following pseudocode?

document.querySelector('.a').WHATEVER.shadowRoot.querySelector('.b').click();

document.querySelector('.a > *:nth-child(1) > *:nth-child(1) > *:nth-child(1)')

(If you don’t tell us what the children are, we cant give you a more specific selector to find said child. Your question has nothing to do with Shadow roots, it’s just asking how to select that third-depth child, which is a generalized problem.)

If, for example, the HTML were

<div class="a">
   <div>
     <div>
        <somethingstrange>
           :shadowRoot

then querySelector(“.a > div > div > *:nth-child(1)”) would find the third-depth child. (I am assuming that the third depth child is randomized, otherwise you’d just search for the specific element name.)
[EDIT: also if the first and/or second depth elements have siblings, you may need to specify :nth-child(1) on them also.]

I am looking for a method that would prevent me of needing to specify anything between the wrapper to the shadow root :slight_smile:

Just telling the computer a directive in the logic of:

Go from this wrapper to the first shadow root in it, from 1 to infinity-by-definition until you get this first shadow root.

Yes, you are looking for the unicorn once again.

The shortest is what you’ve already got, because there isnt a CSS selector for “the shadow root”.

What’s “the first”? Let me give an example.

<div class="firstClass">
   <div>
      <div class="secondClass">A</div>
   </div>
   <div class="secondClass">B</div>
</div>

Which one is the “first”? A comes first if you’re reading the page top to bottom (Depth First), B comes first if you’re reading the page by levels (Breadth First).

I think that I don’t want to select the shadow root itself; I want to select any node that comes after node A, but just before the shadow root that follows node A.

Case 1:

<div></div>
<ow-j3eolsu49kg>
#shadow-root

The cryptic tag will be selected.

Case 2:

<div></div>
<ow-j3eolsu49kg>
<div></div>
<div></div>
<div></div>
#shadow-root

The fourth <div> will be selected.

What would be a good automatic way to select either?

This tells me you’re fundamentally misunderstanding what the shadow-root is.

shadowRoot is a property of an Element that links that element to a shadow-DOM. It’s not an element unto itself.

This… isnt a valid format. At least not in my browser.

EITHER:
the shadowRoot property of the parent is set, in which case the structure upon observation (assuming the shadow root was set to an Open view) would look like

<div class='parent'>
  #shadow-root
  <div></div>
  <ow-j3eolsu49kg>
  <div></div>
  <div></div>
  <div></div>
</div>

Or it’s the shadowRoot property of one of the siblings, in which case it would be presented beneath that sibling:

  <div></div>
  <ow-j3eolsu49kg>
  <div></div>
  <div></div>
  <div>
    #shadow-root
  </div>

Given your first example:

<div></div>
<ow-j3eolsu49kg> <-- note, opening tag only....
#shadow-root

What you’re telling me there is that the shadowRoot property of the “odd” element is set.
So what you’d be looking for is the first element in the set of siblings whose shadowRoot was not null.

Again, AFAIK CSS cant select this property, so querySelector sadly will not be of assistance here.

[...document.getElementById("parent").children].filter(x => x.shadowRoot)[0]
(substitute in however you find the parent element)

1 Like