Even with a name only an engineer could come up with, querySelectorAll() is pretty awesome

January 8th, 2012

One of the reasons I put up tutorials and code on this site is because if something is wrong, someone will let me know, usually within an hour or two of me posting it. I’m actually really happy with how little it happens and most of the time it’s someone pointing out something I missed or a different way of doing it. Recently, I put up a post about the JavaScript method getElementsByClassName where I talked about how it how it might now work the way you would think it should. This lead the a comment saying I should have used querySelectorAll(). So why didn’t I?

Well, the main reason was I didn’t know it could do what I wanted. In every example I’ve seen of querySelectorAll looked like this:

1
var myArray = document.querySelectorAll(‘div’);

I didn’t realize I could pass in a class name and it would select everything with that class:

1
var blueDivs = document.querySelectorAll(‘.blue);

If you take a look at the Mozilla Developer Network page, the example it has is:

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

But up until recently, that was a huge red error message!

So what makes querySelectorAll so great? Well, I made an example that changes the class on a group of divs and then allows you to change it back even though it found the divs in the DOM using the class name. This wouldn’t be possible if I used getElementsByClassName because that live node list would become empty as soon as the class names were changed. Here’s the HTML and CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>querySelectorAll Test #1</title>
<style>
body {
 margin:0;
 padding:0;
}
.wrapper {
 width:550px;
 height:160px;
 margin:30px auto 0;
}
.wrapper > div {
 margin-right:10px;
 float:left;
}
.box {
 background:blue;
 width:100px;
 height:100px;
}
.border {
 background:red;
 width:90px;
 height:90px;
 border:5px solid black;
}
button {
 width:140px;
 height:30px;
 display:block;
 margin:auto;
}
</style>
</head>

<body>
<div class="wrapper">
 <div class="box"></div>
 <div class="box"></div>
 <div class="box"></div>
 <div class="box"></div>
 <div class="box"></div>
</div>
<button id="change">Change the class</button>
</body>
</html>

This just makes five divs that are 100 pixels in width and height with a blue background to start. There a button that when clicked will change the class on the divs. Here’s the JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(function() {
 var boxes = document.querySelectorAll('.box'),
       change = document.getElementById('change'),
       currentClass = 'box';

 if (document.addEventListener) {
   change.addEventListener('click', changeClass, false);
 } else if (document.attachEvent) {
   change.attachEvent('onclick', changeClass);
 }

 function changeClass() {
   if (currentClass === 'box') {
     classLoop('border');
     currentClass = 'border';
   } else if (currentClass === 'border') {
     classLoop('box');
     currentClass = 'box';
   }
 }

 function classLoop(newClass) {
 for (var i = 0; i < boxes.length; i++) {
   boxes[i].className = newClass;
  }
 }
})();

So, when the button is pushed, the class is changed on all five divs from box to border. Check out the demo. And because I used querySelectorAll fo find them in the DOM, then even though the class on all the divs has changed to border, they’re still in the boxes array. This allows the class to be changed back to box when the button is clicked again. I included attachEvent because this will work in Internet Explorer 8, which makes this all kinds of useful!

I have to say, I really wish they’d picked a different name, it’s pretty clunky and doesn’t really describe what it does which I think is important for beginners. I’ll be honest with you, I’ve probably seen this function before but because it’s name, it didn’t catch my eye. I’m sure this makes perfect sense to the people that added it to JavaScript, but really, if you asked someone what it did, they would probably have a hard time guessing.

I’d like to see knowledge of this method spread more to front-end developers that only really know jQuery, because I don’t know how many times I’ve seen jQuery used just to select DOM elements. Hopefully, some devs will start using this so they don’t have to load jQuery just to select some divs.

Leave a Reply

Your email address will not be published. Required fields are marked *