Search code examples
htmlcss-selectorsselectors-api

Querying Html Hierarchy using advanced logic


Given html:

<div data-root="A">
 <div>Ignored</div>
 <div data-child="B">
  <div data-child="C" data-root="E">
    <div data-child="F"></div>
    <div data-child="G">
     <div data-root="Q">
      <div data-child="K"></div>
     </div>
    </div>
  </div>
 </div>
</div>

For any given element (root) I want to query all child elements having data-child attribute populated and not owned by another element with data-root specified.

Sample outcomes:

  • Data Root A: Data children: B, C
  • Data Root E: Data children: F, G, Q
  • Data Root Q: Data children: K

I solved it by calling root.querySelectorAll("[data-child]") and then checking each element individually by tracing it up to the parent while checking if any elements by the way have data-root specified. It works, but the code is a bit awkward for what it's doing. Ideally I'm looking for a codeless declarative solution, can anyone come up with it for my problem?


Solution

  • The only selector-based solution available, in the form

    root.querySelectorAll("[data-child]:not(:scope [data-root] *)")
    

    makes use of Selectors level 4 features that are not yet supported by all browsers and so probably won't work for your needs. There is no such solution available in Selectors level 3.