0

Let's say my code looks like that

const menu = document.querySelector(".menu");

//now i need to select <a> tags with 'design' and 'development', but using menu element i've already selected.

//const firstLineChilds = menu.querySelector(???);
<ul class="menu">
  <li><a href="#">Design</a></li>
  <li><a href="#">Development</a></li>
  <li>
    <ul class="sub-menu">
      <li><a href="#">DevOps</a></li>
      <li><a href="#">Managment</a></li>
    </ul>
  </li>
</ul>

Is it even possible to to this the 'clean way'? Or i just need to use menu.parentNode.querySelector(".menu > li > a")

rudzky
  • 3
  • 4

3 Answers3

0

You can chain querySelector and other such methods and it will search children of previous returned node: document.querySelector(".menu").querySelectorAll("a") or menu.querySelectorAll("a")

Alexey Baguk
  • 168
  • 1
  • 6
0

Converting the hrefs to an Array (in the snippet the spread syntax is used for that) enables you to filter them:

const relevantHrefs = [...document.querySelectorAll(".menu li a")]
  .filter(href => ["Design", "Development"].find(h => href.textContent === h));
console.log(relevantHrefs);

// based on comment, this is maybe what OP needs
const menu = [...document.querySelectorAll(".menu > li:nth-child(-n+2) a")];
console.log(menu);
<ul class="menu">
  <li><a href="#">Design</a></li>
  <li><a href="#">Development</a></li>
  <li>
    <ul class="sub-menu">
      <li><a href="#">DevOps</a></li>
      <li><a href="#">Managment</a></li>
    </ul>
  </li>
</ul>
KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • My point is, it's not about picking two two anchors with specific hrefs, but I would like to pick anchors which are inside first-line childs of ul.menu only. Just tryin to find a way to select them depending on .menu I've already selected. The logic behind this is more complicated, because menu may have diffrent class name, so I want to do this universal and complex way. – rudzky Apr 07 '21 at 11:19
  • Not sure what you mean exactly, but added a css-selector that *may* be what you are looking for. – KooiInc Apr 07 '21 at 11:30
0

Yes, you can use :scope in conjunction with child combinators, in menu.querySelectorAll():

const menu = document.querySelector(".menu")
const firstLineChilds = menu.querySelectorAll(":scope > li > a");
console.log(firstLineChilds);
<ul class="menu">
  <li><a href="#">Design</a></li>
  <li><a href="#">Development</a></li>
  <li>
    <ul class="sub-menu">
      <li><a href="#">DevOps</a></li>
      <li><a href="#">Managment</a></li>
    </ul>
  </li>
</ul>

If you use descendant combinators, you'll still get the nested a elements, which is not what you want. See What does the ">" (greater-than sign) CSS selector mean?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356