152

I'm wondering how to select an element that does not have a specific class using JavaScript, not jQuery.

For example, I have this list:

<ul id="tasks">
  <li class="completed selected">One Task</li>
  <li>Two Task</li>
</ul>

and I select the completed task by:

var completeTask = document.querySelector("li.completed.selected");

But then I'm not sure how to select the list item that does not have those classes.

Popo
  • 2,402
  • 5
  • 33
  • 55
Jaeeun Lee
  • 3,056
  • 11
  • 40
  • 60

6 Answers6

279

This selects the second LI element.

document.querySelector("li:not([class])")

or

document.querySelector("li:not(.completed):not(.selected)")

Example:

// select li which doesn't have a 'class' attribute...
console.log(document.querySelector("li:not([class])"))

// select li which doesn't have a '.completed' and a '.selected' class...
console.log(document.querySelector("li:not(.completed):not(.selected)"))
 <ul id="tasks">
    <li class="completed selected">One Task</li>
    <li>Two Task</li>
  </ul>
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
26

To select the <li> that has not completed nor selected class:

document.querySelector("li:not(.completed):not(.selected)");

Fiddle

http://jsfiddle.net/Z8djF/

BeNdErR
  • 17,471
  • 21
  • 72
  • 103
  • How to [do the reverse](http://stackoverflow.com/q/39822557/2284570) : that is, select all elements that have both`completed`and`selected`class ? – user2284570 Oct 02 '16 at 22:56
  • @user2284570 just write both classes without whitespaces: `li.completed.selected` -> this will match all those `li` elements that have `completed` AND `selected` class – BeNdErR Oct 03 '16 at 08:46
13

You can try the :not() selector

var completeTask = document.querySelector("li:not(.completed):not(.selected)");

http://jsfiddle.net/UM3j5/

Musa
  • 96,336
  • 17
  • 118
  • 137
10

The :not(*selector*) selector also accepts commas (so does querySelectorAll()) https://developer.mozilla.org/en-US/docs/Web/CSS/:not#syntax:

let plainElements = document.querySelectorAll( ':not( .completed, .in-progress ) ');
plainElements.forEach( ( item ) => { item.style.color = 'red'; } );
li { color: green; }
<ul id="tasks">
  <li class="completed selected">Task 1</li>
  <li>Task 2</li>
  <li class="in-progress">Task 3</li>
</ul>
Igor Beuermann
  • 127
  • 1
  • 10
4
document.querySelectorAll('[wf-body=details] input:not(.switch):not(.btn)').forEach(function(e){
    // do whatever you want. with 'e' as element :P
});
Burhan Ibrahimi
  • 367
  • 3
  • 14
1

Try getting an array of the parent's children instead:

var completeTask = document.querySelector("#tasks").childNodes;

Then loop/search them as necessary.

crunch
  • 675
  • 3
  • 8