How to add/remove a class in JavaScript?

JavascriptDomCross Browser

Javascript Problem Overview


Since element.classList is not supported in IE 9 and Safari-5, what's an alternative cross-browser solution?

No-frameworks please.

Solution must work in at least IE 9, Safari 5, FireFox 4, Opera 11.5, and Chrome.

Related posts (but does not contain solution):

  1. https://stackoverflow.com/questions/2170878/how-to-add-and-remove-css-class

  2. https://stackoverflow.com/questions/5084182/add-and-remove-a-class-with-animation

  3. https://stackoverflow.com/questions/3066692/add-remove-class

Javascript Solutions


Solution 1 - Javascript

Here is solution for addClass, removeClass, hasClass in pure javascript solution.

Actually it's from http://jaketrent.com/post/addremove-classes-raw-javascript/

function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className += " "+cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className=ele.className.replace(reg,' ');
  }
}

Solution 2 - Javascript

Look at these oneliners:

  1. Remove class:

    element.classList.remove('hidden');
    
  2. Toggle class (adds the class if it's not already present and removes it if it is)

    element.classList.toggle('hidden');
    

That's all! I made a test - 10000 iterations. 0.8s.

Solution 3 - Javascript

I just wrote these up:

function addClass(el, classNameToAdd){
    el.className += ' ' + classNameToAdd;   
}

function removeClass(el, classNameToRemove){
    var elClass = ' ' + el.className + ' ';
    while(elClass.indexOf(' ' + classNameToRemove + ' ') !== -1){
         elClass = elClass.replace(' ' + classNameToRemove + ' ', '');
    }
    el.className = elClass;
}

I think they'll work in all browsers.

Solution 4 - Javascript

The simplest is element.classList which has remove(name), add(name), toggle(name), and contains(name) methods and is now supported by all major browsers.

For older browsers you change element.className. Here are two helper:

function addClass(element, className){
    element.className += ' ' + className;   
}

function removeClass(element, className) {
    element.className = element.className.replace(
        new RegExp('( |^)' + className + '( |$)', 'g'), ' ').trim();
}

Solution 5 - Javascript

One way to play around with classes without frameworks/libraries would be using the property Element.className, which "gets and sets the value of the class attribute of the specified element." (from the MDN documentation).
As @matías-fidemraizer already mentioned in his answer, once you get the string of classes for your element you can use any methods associated with strings to modify it.

Here's an example:
Assuming you have a div with the ID "myDiv" and that you want to add to it the class "main__section" when the user clicks on it,

window.onload = init;

function init() {
  document.getElementById("myDiv").onclick = addMyClass;
}

function addMyClass() {
  var classString = this.className; // returns the string of all the classes for myDiv
  var newClass = classString.concat(" main__section"); // Adds the class "main__section" to the string (notice the leading space)
  this.className = newClass; // sets className to the new string
}

Solution 6 - Javascript

Read this Mozilla Developer Network article:

Since element.className property is of type string, you can use regular String object functions found in any JavaScript implementation:

  • If you want to add a class, first use String.indexOf in order to check if class is present in className. If it's not present, just concatenate a blank character and the new class name to this property. If it's present, do nothing.

  • If you want to remove a class, just use String.replace, replacing "[className]" with an empty string. Finally use String.trim to remove blank characters at the start and end of element.className.

Solution 7 - Javascript

Fixed the solution from @Paulpro

  1. Do not use "class", as it is a reserved word
  2. removeClass function was broken, as it bugged out after repeated use.

`

function addClass(el, newClassName){
    el.className += ' ' + newClassName;   
}

function removeClass(el, removeClassName){
    var elClass = el.className;
    while(elClass.indexOf(removeClassName) != -1) {
        elClass = elClass.replace(removeClassName, '');
        elClass = elClass.trim();
    }
    el.className = elClass;
}

Solution 8 - Javascript

The solution is to

Shim .classList:

Either use the DOM-shim or use Eli Grey's shim below

Disclaimer: I believe the support is FF3.6+, Opera10+, FF5, Chrome, IE8+

/*
 * classList.js: Cross-browser full element.classList implementation.
 * 2011-06-15
 *
 * By Eli Grey, http://eligrey.com
 * Public Domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */

/*global self, document, DOMException */

/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/

if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {

(function (view) {

"use strict";

var
	  classListProp = "classList"
	, protoProp = "prototype"
	, elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
	, objCtr = Object
	, strTrim = String[protoProp].trim || function () {
		return this.replace(/^\s+|\s+$/g, "");
	}
	, arrIndexOf = Array[protoProp].indexOf || function (item) {
		var
			  i = 0
			, len = this.length
		;
		for (; i < len; i++) {
			if (i in this && this[i] === item) {
				return i;
			}
		}
		return -1;
	}
	// Vendors: please allow content code to instantiate DOMExceptions
	, DOMEx = function (type, message) {
		this.name = type;
		this.code = DOMException[type];
		this.message = message;
	}
	, checkTokenAndGetIndex = function (classList, token) {
		if (token === "") {
			throw new DOMEx(
				  "SYNTAX_ERR"
				, "An invalid or illegal string was specified"
			);
		}
		if (/\s/.test(token)) {
			throw new DOMEx(
				  "INVALID_CHARACTER_ERR"
				, "String contains an invalid character"
			);
		}
		return arrIndexOf.call(classList, token);
	}
	, ClassList = function (elem) {
		var
			  trimmedClasses = strTrim.call(elem.className)
			, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
			, i = 0
			, len = classes.length
		;
		for (; i < len; i++) {
			this.push(classes[i]);
		}
		this._updateClassName = function () {
			elem.className = this.toString();
		};
	}
	, classListProto = ClassList[protoProp] = []
	, classListGetter = function () {
		return new ClassList(this);
	}
;
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i) {
	return this[i] || null;
};
classListProto.contains = function (token) {
	token += "";
	return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function (token) {
	token += "";
	if (checkTokenAndGetIndex(this, token) === -1) {
		this.push(token);
		this._updateClassName();
	}
};
classListProto.remove = function (token) {
	token += "";
	var index = checkTokenAndGetIndex(this, token);
	if (index !== -1) {
		this.splice(index, 1);
		this._updateClassName();
	}
};
classListProto.toggle = function (token) {
	token += "";
	if (checkTokenAndGetIndex(this, token) === -1) {
		this.add(token);
	} else {
		this.remove(token);
	}
};
classListProto.toString = function () {
	return this.join(" ");
};

if (objCtr.defineProperty) {
	var classListPropDesc = {
		  get: classListGetter
		, enumerable: true
		, configurable: true
	};
	try {
		objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
	} catch (ex) { // IE 8 doesn't support enumerable:true
		if (ex.number === -0x7FF5EC54) {
			classListPropDesc.enumerable = false;
			objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
		}
	}
} else if (objCtr[protoProp].__defineGetter__) {
	elemCtrProto.__defineGetter__(classListProp, classListGetter);
}

}(self));

}

Solution 9 - Javascript

Improved version of emil's code (with trim())

function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className = ele.className.trim() + " " + cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className = ele.className.replace(reg,' ');
    ele.className = ele.className.trim();
  }
}

Solution 10 - Javascript

function addClass(element, classString) {
    element.className = element
        .className
        .split(' ')
        .filter(function (name) { return name !== classString; })
        .concat(classString)
        .join(' ');
}

function removeClass(element, classString) {
    element.className = element
        .className
        .split(' ')
        .filter(function (name) { return name !== classString; })
        .join(' ');
}

Solution 11 - Javascript

Just in case if anyone would like to have prototype functions built for elements, this is what I use when I need to manipulate classes of different objects:

Element.prototype.addClass = function (classToAdd) {
  var classes = this.className.split(' ')
  if (classes.indexOf(classToAdd) === -1) classes.push(classToAdd)
  this.className = classes.join(' ')
}

Element.prototype.removeClass = function (classToRemove) {
  var classes = this.className.split(' ')
  var idx =classes.indexOf(classToRemove)
  if (idx !== -1) classes.splice(idx,1)
  this.className = classes.join(' ')
}

Use them like: document.body.addClass('whatever') or document.body.removeClass('whatever')

Instead of body you can also use any other element (div, span, you name it)

Solution 12 - Javascript

add css classes: cssClassesStr += cssClassName;

remove css classes: cssClassStr = cssClassStr.replace(cssClassName,"");

add attribute 'Classes': object.setAttribute("class", ""); //pure addition of this attribute

remove attribute: object.removeAttribute("class");

Solution 13 - Javascript

A easy to understand way:

// Add class 
DOMElement.className += " one";
// Example:
// var el = document.body;
// el.className += " two"

// Remove class 
function removeDOMClass(element, className) {
    var oldClasses      = element.className,
        oldClassesArray = oldClasses.split(" "),
        newClassesArray = [],
        newClasses;

    // Sort
    var currentClassChecked,
        i;     
    for ( i = 0; i < oldClassesArray.length; i++ ) { 
        // Specified class will not be added in the new array
        currentClassChecked = oldClassesArray[i];
        if( currentClassChecked !== className ) { 
            newClassesArray.push(currentClassChecked);
        }
    }

    // Order 
    newClasses = newClassesArray.join(" ");

    // Apply     
    element.className = newClasses;

    return element;

}
// Example:
// var el = document.body;
// removeDOMClass(el, "two")

https://gist.github.com/sorcamarian/ff8db48c4dbf4f5000982072611955a2

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPacerierView Question on Stackoverflow
Solution 1 - JavascriptemilView Answer on Stackoverflow
Solution 2 - JavascriptSergio BelevskijView Answer on Stackoverflow
Solution 3 - JavascriptPaulView Answer on Stackoverflow
Solution 4 - JavascriptWernightView Answer on Stackoverflow
Solution 5 - JavascriptYago DLTView Answer on Stackoverflow
Solution 6 - JavascriptMatías FidemraizerView Answer on Stackoverflow
Solution 7 - JavascriptDrewView Answer on Stackoverflow
Solution 8 - JavascriptRaynosView Answer on Stackoverflow
Solution 9 - JavascriptvagovszkymView Answer on Stackoverflow
Solution 10 - Javascriptscott_trinhView Answer on Stackoverflow
Solution 11 - JavascriptJoanna BetlejView Answer on Stackoverflow
Solution 12 - JavascriptReporterView Answer on Stackoverflow
Solution 13 - JavascriptMarian07View Answer on Stackoverflow