1

I want to match all h1's on the document except from a div containing other h1's, currently i can do querySelectorAll('h1:not(.demo)) to get all h1's with except h1's with demo class.

But how can i do querySelectorAll('h1:not(div#demo)) or similar thing?

Below is a sample html

<body>
  <div><h1>First</h1> <h1>Second</h1></div>
  <div id="demo"><h1 class="demo">Third</h1></div>
  <div><h1>Fourth</h1></div>
<body>
Gopal Sharma
  • 755
  • 1
  • 12
  • 25
  • please share your html? – brk May 31 '19 at 07:48
  • try ```document.querySelectorAll('div:not(#demo) h1')``` – AsukaSong May 31 '19 at 07:56
  • I guess [slightly related](https://stackoverflow.com/questions/7084112/css-negation-pseudo-class-not-for-parent-ancestor-elements) - interestingly, it's again about selecting all `h1` elements unless the parent is `div`. – VLAZ May 31 '19 at 07:57
  • @AsukaSong [doesn't work](https://jsbin.com/mezupileyu/edit?html,css,js,console,output) in either CSS nor `querySelectorAll` EDIT: ugh, sorry - OP changed the HTML, I was using the old one... [It does work](https://jsbin.com/pujibenoti/1/edit?html,css,js,console,output) – VLAZ May 31 '19 at 07:59

4 Answers4

1

either this will work

 document.querySelectorAll('div:not(#demo) h1')

or this

document.querySelectorAll('h1:not(.demo)')

if you want to target all h1 where don't have a class attribute you can do this way

document.querySelectorAll('h1:not([class])')

read more about :not

Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91
0

You can first get all the divs except those you want to match, then run a query selector from those:

const divsWhichArentDemo = document.querySelectorAll('div:not(#demo)');
const h1sWhichArentInDemoDivs = Array.prototype.slice.call(divsWhichArentDemo)
  .map(div => Array.prototype.slice.call(div.querySelectorAll('h1')))
  .flat();
  

console.dir(h1sWhichArentInDemoDivs);
<div>
  <h1>First</h1>
  <h1>Second</h1>
</div>
<div id="demo">
  <h1 class="demo">Third</h1>
</div>
<div>
  <h1>Fourth</h1>
</div>
OliverRadini
  • 6,238
  • 1
  • 21
  • 46
0

You can quite select the child headings from the divs with >h1

let h1 = document.querySelectorAll('div:not(#demo)>h1');

console.log(h1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><h1>First</h1> <h1>Second</h1></div>
<div id="demo"><h1 class="demo">Third (demo)</h1></div>
<div><h1>Fourth</h1></div>
Matt Ellen
  • 11,268
  • 4
  • 68
  • 90
0

You can exclude div from collection by this way: ':not(div) > h1':

var s = document.querySelectorAll(':not(div) > h1');
[...s].forEach((el) => el.innerHTML += ' changed');
<div >
      <h1>h inside div 1</h1>
</div>
<h1>h outside div 1</h1>
<div id="d2">
      <h1>h inside div 2</h1>
</div>
<h1>h outside div 2</h1>

You may set a selector ':not(#demo) > h1' then all h1 will be treated except those ones inside #demo:

var s = document.querySelectorAll(':not(#demo) > h1');
[...s].forEach((el) => el.innerHTML += ' changed');
<div >
      <h1>h inside div 1</h1>
</div>
<h1>h outside div 1</h1>
<div id="demo">
      <h1>h inside div #demo</h1>
</div>
<h1>h outside div demo</h1>
Banzay
  • 9,310
  • 2
  • 27
  • 46