How to target ALL elements in shadow-root?

209 views Asked by At

I am trying to add a class to an element inside of the shadow root for 3 slides within a carousel. Here is my code:

let modalFlexDisplay = document.querySelector("#ipm-ad-modal-div")
                     .querySelector("#rs-two-col")
                     .shadowRoot.querySelector(".wrapper");

modalFlexDisplay.classList.add("hidden");
<div id="ipm-ad-modal-div">
  <div id="rs-two-col">
    <template shadowrootmode="open">
      <div class="wrapper">
        <p>hello and happy halloween</p>
      </div>
    </template>
  </div>
  <div id="rs-two-col">
    <template shadowrootmode="open">
      <div class="wrapper">
        <p>hello and happy halloween</p>
      </div>
    </template>
  </div>
</div>

If you inspect the code snippet here, you can see that the class was successfully added to just the first div.wrapper tag. However I want to add them on all, and not just the first one.

When I try to add "querySelectorAll" to any or all of the elements, it returns an error saying it cannot read the properties of querySelector. How do i add the class "hidden" to all elements within each shadow root?

1

There are 1 answers

2
Danny '365CSI' Engelman On BEST ANSWER

You have multiple hurdles, and duplicate IDs is not one of them

  • shadowrootmode is for a Declarative ShadowDOM, not yet supported in FireFox, soon will be

  • You don't show any CSS for your hidden class. It needs to go inside the shadowDOM

  • querySelectorAll selects multiple elements you have to loop over to dive into its shadowRoot, then set the hidden class

document.querySelectorAll("#subdiv").forEach(subdiv => {
  let shadowdiv = subdiv.shadowRoot.querySelector(".wrapper");
  shadowdiv.classList.add("hidden");
});

// ?? WTF did Microsoft do 25 years ago?
console.log( maindiv );
console.log( subdiv[0] );

// no need for querySelector.. in Chrome and Safari
[...subdiv].forEach( s => s.style.color = "blue" );
<div id="maindiv">
  <div id="subdiv" ONE>
    <template shadowrootmode="open">
      <style>
        .hidden { background:red }
      </style>
      <div class="wrapper" >
        <p>hello and happy halloween</p>
      </div>
    </template>
  </div>
  <div id="subdiv" TWO>
    <template shadowrootmode="open">
      <style>
        .hidden { background:coral }
      </style>
      <div class="wrapper" >
        <p>hello and happy halloween</p>
      </div>
    </template>
  </div>
</div>

Duplicats IDs

Note duplicate IDs are no issue at all; Microsoft Internet Explorer (then the dominant browser) allowed for duplicates since its first release in the previous century; and every newer browser copied its behavior since.

You better not (I never say should not) use duplicate IDs because its like calling all your children "X", and that's confusing (unless your first name is Elon)

As you can see in the console.log IDs create global variables; behavior is slightly different for duplicate IDs in FireFox since a FireFox patch in 2017

Interesting to use in test code; but you shouldn't use this in production code... darn I said should.. because most of your "experienced" team-members won't have a clue what is going on.