1

I have an outer element that retrieved by document.getElementById (I can't change this part as the outer variable was passed in by other code). How to get its direct child element that have class inner? I've tried outer.querySelectorAll(".inner"), which will get all .inner elements (see below demo). I only want the direct child and have .inner. I also tried outer.querySelectorAll("> .inner"), but it doesn't work. How can I do that?

var outer = document.getElementById("outer");
var all = outer.querySelectorAll(".inner");
all.forEach(function(e){
    e.style.border = "1px solid red";
});
<div id="outer">
  <div class="inner">inner</div>
  <div id="test">
    <div class="inner">inner2</div>
  </div>
</div>
Just a learner
  • 26,690
  • 50
  • 155
  • 234

1 Answers1

4

If outer is already in a variable, you can use :scope at the start of a query string with querySelectorAll to "select" the element the querySelectorAll is being called on:

var outer = document.getElementById("outer");
outer.querySelectorAll(":scope > .inner").forEach((e) => {
  e.style.border = "1px solid red";
});
<div id="outer">
  <div class="inner">inner</div>
  <div id="test">
    <div class="inner">inner2</div>
  </div>
</div>

If you don't have to have outer already in a variable, it would be easier to use the plain query string #outer > .inner:

document.querySelectorAll("#outer > .inner").forEach((e) => {
  e.style.border = "1px solid red";
});
<div id="outer">
  <div class="inner">inner</div>
  <div id="test">
    <div class="inner">inner2</div>
  </div>
</div>

Rather than iterating over all child elements, a different approach would be to toggle a class on outer, while having a CSS rule which applies to direct children of outer while outer has that class:

document.querySelector('#outer').classList.add('red');
#outer.red > .inner {
  border: 1px solid red;
}
<div id="outer">
  <div class="inner">inner</div>
  <div id="test">
    <div class="inner">inner2</div>
  </div>
</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320