How to add/remove a class in JavaScript?

98,600

Solution 1

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 2

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 3

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 4

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 5

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();
}
Share:
98,600

Related videos on Youtube

Pacerier
Author by

Pacerier

# 9

Updated on July 05, 2022

Comments

  • Pacerier
    Pacerier about 2 years

    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. how to add and remove css class

    2. Add and remove a class with animation

    3. Add remove class?

    • davin
      davin almost 13 years
      I will never understand the need for cross-browser compatible code and the refusal to use a framework. That's their very purpose. It's like trying to eat spaghetti but refusing to use a fork, sure you can get by but it's messy.
    • Matías Fidemraizer
      Matías Fidemraizer almost 13 years
      +1 @davin. But, anyway, some professional projects with less professional project managers or responsibles of some projects are rejecting the use of frameworks because of other non-professional customer decisions.
    • Raynos
      Raynos almost 13 years
      @davin there's a difference between frameworks and shims. Shims are also valid.
    • davin
      davin almost 13 years
      @Raynos, most of the time what you think is going to be just one shim ends up being five, which leads to much less maintainable, less tested code that would be better replaced by a framework.
    • Raynos
      Raynos almost 13 years
      @davin You just need one shim. It's called the DOM shim. Then you just write standards compliant code. You do need a framework, it's called the DOM.
    • Pacerier
      Pacerier almost 13 years
      @davin because eating spaghetti with a fork doesn't mean that you are not allowed to understand how a fork works.
    • davin
      davin almost 13 years
      @Pacerier, who said anything about understanding how things work? Your question seems to be one of implementation, not understanding. If your goal is to understand then look at the source code of any of the frameworks that do this stuff (github.com/jquery/jquery/blob/master/src/attributes.js#L39)‌​. That is very much distinct from whether or not it's a good design decision to implement.
    • Pacerier
      Pacerier almost 13 years
      my question is one of understanding. you assumed wrongly
    • thejustv
      thejustv over 8 years
  • Gareth
    Gareth almost 13 years
    This doesn't work, for example if you try to remove the only class on an element (which doesn't have a space either side of its name)
  • Paul
    Paul almost 13 years
    @Gareth, that will work. It inserts a space on each side in line one of removeClass.
  • xusame
    xusame over 12 years
    Definitely a clever shim. It works in FF at least down to 1.5 (can't test below that). It breaks in IE7 and below. For that reason it is next-to-useless on real sites for anything essential. For real use, go with a framework.
  • Raynos
    Raynos over 12 years
    @theazureshadow psh, Legacy support is for enterprise solutions, who cares about IE7 outside of the enterprise world.
  • xusame
    xusame over 12 years
    If you care about the 12 percent of users (about one in 8) who currently use IE7 and below (source: marketshare.hitslink.com). I think iOS 5 is the first iOS version to support it, too, so at the time of your posting no iPhone users would be supported. Talk about legacy!
  • Raynos
    Raynos over 12 years
    @theazureshadow meh, IE7 doesn't need javascript. And mobiles is a whole different ball game. (The shim should work on mobiles)
  • xusame
    xusame over 12 years
    You're right about mobile. It will really be up to individual cases whether IE7 support is worth it. Most people will find it easily worth it to use a framework to smooth out browser differences -- far beyond classList availability. "IE7 doesn't need javascript" is an extremely questionable statement.
  • Raynos
    Raynos over 12 years
    @theazureshadow your HTML/CSS website looks fine without javascript in IE7 and if your making a web application for IE7 then I feel your pain, really ask yourself whether that extra 300% effort to get IE7 to work is worth it. (99% it isnt for me)
  • Bali Balo
    Bali Balo over 10 years
    That will not work. If element has class 'a b c' and you try to remove b, it will set new class to ' ac '. So you have to change '' by ' ' in the replace function. Moreover, class is a reserved keyword.
  • Drew
    Drew about 10 years
    I've fixed your solution to 1. Not use "class", which is a reserved word 2. Your broken removeClass method, which creates tons of clutter after repeated use due to whitespace not being trimmed See solution below as an answer.
  • Motin
    Motin about 9 years
    How can this be the accepted answer then the question includes "remove" class but this answer not?
  • Filip Cornelissen
    Filip Cornelissen about 9 years
    I used this code with the addition of this code just after the replace statement: while (elClass[0] === " ") elClass = elClass.substr(1); while (elClass[elClass.length - 1] === " ") elClass = elClass.substr(0, elClass.length - 1); This will delete the leading and trailing space which might still be present
  • leafiy
    leafiy almost 9 years
    .replace(/\bexmaple\b/, "")
  • George Carlin
    George Carlin about 8 years
    fore those people who want's to use this, change class word to theClass like this function(el, theClass){...};
  • Warren Spencer
    Warren Spencer about 8 years
    Note that classList is not supported in IE 9 which is stated in OP's question
  • JoeTidee
    JoeTidee about 7 years
    SHouldn't you be checking if the class name exists before adding it?
  • keaton
    keaton over 6 years
    if(el.className.indexOf(' ' + className) != -1) return; to addClass would help
  • Kyle Baker
    Kyle Baker about 6 years
    while it doesn't satisfy a restraint that was extremely particular to OP, I think this question gets looked at by many people hoping for an answer to the general question without those specific restraints. I was very happy to find this, and only noticed it on my second visit. I'm glad I did--much cleaner solution. Thanks!
  • neoexpert
    neoexpert over 4 years
    this does not work for a svg element created with "createElementNS". How can this be achived?
  • neoexpert
    neoexpert over 4 years
    this does not work for a svg element created with "createElementNS". How can this be achived?