173

Is it possible to make a search by querySelectorAll using multiple unrelated conditions? If yes how? And how to specify whether those are AND or OR criteria?

For example:

How to find all forms, ps and legends with a single querySelectorAll call? Possible?

Alan Coromano
  • 23,626
  • 48
  • 130
  • 190
  • I'm not sure what you mean by "*AND or OR criteria*". Can you give an example for that? – Bergi Nov 30 '15 at 15:26
  • 5
    [The documentation covers this in the first example](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll). – Andy Nov 30 '15 at 15:28

5 Answers5

272

Is it possible to make a search by querySelectorAll using multiple unrelated conditions?

Yes, because querySelectorAll accepts full CSS selectors, and CSS has the concept of selector groups, which lets you specify more than one unrelated selector. For instance:

var list = document.querySelectorAll("form, p, legend");

...will return a list containing any element that is a form or p or legend.

CSS also has the other concept: Restricting based on more criteria. You just combine multiple aspects of a selector. For instance:

var list = document.querySelectorAll("div.foo");

...will return a list of all div elements that also (and) have the class foo, ignoring other div elements.

You can, of course, combine them:

var list = document.querySelectorAll("div.foo, p.bar, div legend");

...which means "Include any div element that also has the foo class, any p element that also has the bar class, and any legend element that's also inside a div."

T.J. Crowder
  • 959,406
  • 173
  • 1,780
  • 1,769
  • is there a possibility to use a single class from document.querySelectorAll, for example I have var hotspots = document.querySelectorAll(".clickMapItem.text , .clickMapItem.multiImageText"); var i; for (i = 0; i < hotspots.length; i++) { hotspots[i].style.display = "none"; } I need to use if else statement, how to check whether it is a class display none or something else. if (hotspots[0 or 1].style.display == "none") doesn't work. – Mile Mijatović Nov 05 '16 at 09:18
  • 2
    @MileMijatovic: Questions should be posted as questions rather than comments. But see: http://stackoverflow.com/questions/25238153/how-to-get-background-color-property-value-in-javascript/25238247#25238247 – T.J. Crowder Nov 05 '16 at 09:22
  • Ok, but in general, is it possible to do what I asked? The link did not help – Mile Mijatović Nov 05 '16 at 10:04
  • The selector groups concept worked for me still in 2018... thanks for sharing – Eric Hepperle - CodeSlayer2010 Oct 18 '18 at 15:16
  • Year after year, I still use `document.querySelectorAll("div.foo", "div.bar")` and it never worked. Code UX is the next UX ;) – Gabriel Glenn Feb 12 '21 at 13:54
27

According to the documentation, just like with any css selector, you can specify as many conditions as you want, and they are treated as logical 'OR'.

This example returns a list of all div elements within the document with a class of either "note" or "alert":

var matches = document.querySelectorAll("div.note, div.alert");

source: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

Meanwhile to get the 'AND' functionality you can for example simply use a multiattribute selector, as jquery says:

https://api.jquery.com/multiple-attribute-selector/

ex. "input[id][name$='man']" specifies both id and name of the element and both conditions must be met. For classes it's as obvious as ".class1.class2" to require object of 2 classes.

All possible combinations of both are valid, so you can easily get equivalent of more sophisticated 'OR' and 'AND' expressions.

mikus
  • 2,647
  • 25
  • 35
  • 2
    While the method itself is correct, there's no need to reference jQuery to explain CSS (especially since the OP's question is limited to JavaScript). – Chaya Cooper Dec 18 '19 at 19:58
8

With pure JavaScript you can do this (such as SQL) and anything you need, basically:

<html>

<body>

<input type='button' value='F3' class="c2" id="btn_1">
<input type='button' value='F3' class="c3" id="btn_2">
<input type='button' value='F1' class="c2" id="btn_3">

<input type='submit' value='F2' class="c1" id="btn_4">
<input type='submit' value='F1' class="c3" id="btn_5">
<input type='submit' value='F2' class="c1" id="btn_6">

<br/>
<br/>

<button onclick="myFunction()">Try it</button>

<script>
    function myFunction() 
    {
        var arrFiltered = document.querySelectorAll('input[value=F2][type=submit][class=c1]');

            arrFiltered.forEach(function (el)
            {                
                var node = document.createElement("p");
                
                node.innerHTML = el.getAttribute('id');

                window.document.body.appendChild(node);
            });
        }
    </script>

</body>

</html>
double-beep
  • 4,567
  • 13
  • 30
  • 40
Alejandro D.V.
  • 153
  • 1
  • 5
  • 1
    this doesn't really answer the question, specifically the `how to specify whether those are AND or OR criteria` part, see accepted answer – Meidan Alon Mar 21 '19 at 20:36
4

Yes, querySelectorAll does take a group of selectors:

form, p, legend
Bergi
  • 572,313
  • 128
  • 898
  • 1,281
0

Using just document.querySelectorAll('selector1, selector2, selector3') didn't work for me, had to use forEach() method alongside to achieve the desired result.

document.querySelectorAll('selector1, selector2, selector3').forEach(item => {
        item.//code
    })

document.querySelectorAll('#id1, #id2, #id3').style = 'background-color: red';
document.querySelectorAll('#id4, #id5, #id6').forEach(item => {
    item.style = 'background-color: red';
})
<div id="id1">id1</div>
<div id="id2">id2</div>
<div id="id3">id3</div>
<div id="id4">id4</div>
<div id="id5">id5</div>
<div id="id6">id6</div>
first user
  • 56
  • 1
  • 4