CSS descendent selector to get all elements with a certain attribute, ignoring any that are descendents of an element with that same attribute

Viewed 33

I'm using element attributes to identify a tree-like structure in the DOM and each node that branches looks after its children. It does so by searching descendents of the node in the DOM and checking for the attribute that identifies another node. It needs to do this since the child nodes might be several layers deeper in the DOM.

I'm currently doing this with the following JS:

const directChildNodes = [...nodeElement.querySelectorAll(`[tree-node-name="${this.treeName}"]`)]
  // filter all results where the current node is the closest parent
  .filter((el: Element) =>
    el.parentElement?.closest(`[tree-node-name="${this.treeName}"]`) === this.host.nativeElement);

This works, but is not very efficient as it grabs all elements with the attribute and then filters out ones that don't identify the current node as the closest parent. I would ideally be able to achieve this in the CSS selector.

I've tried the following selector but this does not seem to work:

nodeElement.querySelectorAll(
  `[tree-node-name="${this.treeName}"]:not([tree-node-name="${this.treeName}"] [tree-node-name="${this.treeName}"])`
)]

Any suggestions would be great, thanks!

1 Answers

What about using the :scope pseudo class:

nodeElement.querySelectorAll(':scope > [tree-node-name="${this.treeName}"]')

It's not supported in IE but it's supported in most browsers.

Related