15

How can I add/remove a single class on multiple class-selected elements.

In my setup I have some variables cached for doesn't stuff to each:

var classOne    = document.querySelector(".class1");
var classTwo    = document.querySelector(".class2");
var classThree  = document.querySelector(".class3");
var classFour   = document.querySelector(".class4");

but I'm also trying to do something like this:

var allClasses = [classOne, classTwo, classThree, classFour];

allClasses.classList.add("active");
allClasses.classList.remove("active");

Doesn't seem to be working though.

No jQuery please.

user3143218
  • 1,738
  • 5
  • 32
  • 48
  • Maybe that will help you http://stackoverflow.com/questions/2155737/remove-css-class-from-element-with-javascript-no-jquery – Alex Char May 09 '14 at 13:15
  • A couple of things to watch out for: `classList` is not supported in IE8 or IE9. (It can be [shimmed](https://github.com/remy/polyfills/blob/master/classList.js), though.) Also, `querySelector` finds the **first** matching element in the DOM. – T.J. Crowder May 09 '14 at 13:18

2 Answers2

15

Try this:

var classOne    = document.querySelector(".class1");
var classTwo    = document.querySelector(".class2");
var classThree  = document.querySelector(".class3");
var classFour   = document.querySelector(".class4");

var allClasses = [classOne, classTwo, classThree, classFour];

allClasses.forEach(function(el) {
  el.classList.add("active")
})
bottens
  • 3,834
  • 1
  • 13
  • 15
  • 1
    @user3143218: Presumably "el" means the element in the array, whether you take "element" to mean "array element" or "DOM element". :-) – T.J. Crowder May 09 '14 at 13:21
  • 1
    Array.prototype.forEach passes in the value of the index it is at. Which in this case will be elements. @T.J.Crowder I was going for DOM elements but good point :) – bottens May 09 '14 at 13:22
11

Now this can be simplified to:

document.querySelectorAll('.class1, .class2, .class3, .class4').forEach(el => el.classList.add('active'))

If you need legacy browser support, use a regular function or transpile and include this polyfill:

if (window.NodeList && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = function (callback, thisArg) {
        thisArg = thisArg || window
        for (let i = 0; i < this.length; i++) {
            callback.call(thisArg, this[i], i, this)
        }
    }
}

If you use querySelectorAll a lot, you can bind it to a variable:

const $$ = document.querySelectorAll.bind(document)

$$('.class1, .class2, .class3, .class4').forEach(el => el.classList.add('active'))
Fabian von Ellerts
  • 4,763
  • 40
  • 35