1

How can i include all .article-full h2 and .article-full h3 from the DOM structure except the h2 and h3 contained in .toc-excluded

I tried

const headings = document.querySelectorAll(
  ".article--full :not(.toc-excluded) h2, .article--full :not(.toc-excluded) h3"
);
headings.forEach(hd => hd.classList.add("red"))
.red {
  color: red;
}
<div class='article--full'>
  <div>many divs in between</div>
  <div class='toc-excluded'>
    <div>many divs in between</div>
    <h2>h2</h2>
    <h3>h3</h3>
  </div>
  <div>many divs in between</div>
  <div class='manyotherdivs'><h2>h2</h2></div>
   <div class='manyotherdivs'><h3>h3</h3></div>
</div>
Matoeil
  • 6,851
  • 11
  • 54
  • 77
  • 1
    I made you a [mcve] You could have done that too – mplungjan Jul 15 '20 at 09:34
  • 1
    I don't know whether a CSS selector will be able to do this alone. It's just not designed for this kind of scenario. You may need to just get all h2/h3s and check their parent in code – Liam Jul 15 '20 at 09:55
  • Your current code snippet seems to be working. It's edited a few times, does this still accurately depict your scenario? – 3limin4t0r Jul 15 '20 at 10:14
  • @3limin4t0r The current snippet selects the last two H* elements, I've understood the question so, that the first two h* elements should be excluded from the NodeList, i.e. everything but the first two H*s should appear red. – Teemu Jul 15 '20 at 10:56
  • @Teemu i don't quite get it. it seems to be dependant of some divs in between . why are the .toc-excluded h3s are not excluded in here https://codepen.io/matoeil/pen/eYJLPjP ? – Matoeil Jul 15 '20 at 11:32
  • The syntaxes `:not` and `:not()` are not supported in all browsers. In those browsers these syntaxes are supported, I suppose `.article--full :not(.toc-excluded h2, .toc-excluded h3)` would work. – Teemu Jul 15 '20 at 11:52
  • @teemu it does not seem to work in my codepen. How could i select all h2s and h3s then remove the ones with .toc-excluded parents? – Matoeil Jul 15 '20 at 11:55
  • It looks like I can't create such a selector using Firefox (that doesn't mean it would be impossible). Maybe you should go with Liam's suggestion ..? (In my tests the descendant combinator selects all inspite of `:not`, and using a complex selector within `:not` causes a CSS error.) – Teemu Jul 15 '20 at 11:58
  • @Teemu that's what i am trying now without success, removing nodes from the nodelist depending on the parent . – Matoeil Jul 15 '20 at 12:03
  • NodeList is read-only, convert it to an array and use that array instead of the list. – Teemu Jul 15 '20 at 12:09

1 Answers1

1

All the syntaxes of :not are not fully supported yet, hence it's better to rely on old good JS instead. As Liam suggested, you've to filter the elements you want to exclude out of the list, like this:

const headings = Array.from(
    document.querySelectorAll('.article--full h2, .article--full h3')
  ).filter(el => !el.closest('.toc-excluded'));

headings.forEach(hd => hd.classList.add("red"));
.red {
  color: red;
}

h2,
h3 {
  color: black;
}
<div class="article--full">
  <div>many divs in between</div>
  <div class="toc-excluded">
    <div>many divs in between</div>
    <h2>h2</h2>
    <h3>h3</h3>
  </div>
  <div>many divs in between</div>
  <div class="manyotherdivs">
    <h2>h2</h2>
  </div>
  <div class="manyotherdivs">
    <h3>h3</h3>
  </div>
</div>

The returned NodeList must be converted to an array before filtering, since the list itself is read-only, and it doesn't support filter method. The header elements need their own CSS, otherwise the font color is inherited, and there wouldn't be any visual difference.

Teemu
  • 22,918
  • 7
  • 53
  • 106
  • the divs should not be red as there are no headers – Matoeil Jul 15 '20 at 12:37
  • as a complement to Teemu reply , i have sorted myself once the nodelist converted to array as such https://codepen.io/matoeil/pen/BajOGMq – Matoeil Jul 15 '20 at 12:41
  • 1
    @Matoeil The question was "_How can I exclude the h2 and h3 contained in `.toc-excluded`_", there were no other conditions. Please describe the wanted result more accurately, I can fix the answer correspondingly. – Teemu Jul 15 '20 at 12:42
  • i have editd the question trying to be more precise – Matoeil Jul 15 '20 at 13:44