[javascript] Check if an element contains a class in JavaScript?

Using plain JavaScript (not jQuery), Is there any way to check if an element contains a class?

Currently, I'm doing this:

_x000D_
_x000D_
var test = document.getElementById("test");_x000D_
var testClass = test.className;_x000D_
_x000D_
switch (testClass) {_x000D_
  case "class1":_x000D_
    test.innerHTML = "I have class1";_x000D_
    break;_x000D_
  case "class2":_x000D_
    test.innerHTML = "I have class2";_x000D_
    break;_x000D_
  case "class3":_x000D_
    test.innerHTML = "I have class3";_x000D_
    break;_x000D_
  case "class4":_x000D_
    test.innerHTML = "I have class4";_x000D_
    break;_x000D_
  default:_x000D_
    test.innerHTML = "";_x000D_
}
_x000D_
<div id="test" class="class1"></div>
_x000D_
_x000D_
_x000D_

The issue is that if I change the HTML to this...

<div id="test" class="class1 class5"></div>

...there's no longer an exact match, so I get the default output of nothing (""). But I still want the output to be I have class1 because the <div> still contains the .class1 class.

This question is related to javascript html css dom

The answer is


className is just a string so you can use the regular indexOf function to see if the list of classes contains another string.


Tip: Try to remove dependencies of jQuery in your projects as much as you can - VanillaJS.

document.firstElementChild returns <html> tag then the classList attribute returns all classes added to it.

if(document.firstElementChild.classList.contains("your-class")){
    // <html> has 'your-class'
} else {
    // <html> doesn't have 'your-class'
}

If the element only has one class name you can quickly check it by getting the class attribute. The other answers are much more robust but this certainly has it's use cases.

if ( element.getAttribute('class') === 'classname' ) {

}

  1. Felix's trick of adding spaces to flank the className and the string you're searching for is the right approach to determining whether the elements has the class or not.

  2. To have different behaviour according to the class, you may use function references, or functions, within a map:

    function fn1(element){ /* code for element with class1 */ }
    
    function fn2(element){ /* code for element with class2 */ }
    
    function fn2(element){ /* code for element with class3 */ }
    
    var fns={'class1': fn1, 'class2': fn2, 'class3': fn3};
    
    for(var i in fns) {
        if(hasClass(test, i)) {
            fns[i](test);
        }
    }
    
    • for(var i in fns) iterates through the keys within the fns map.
    • Having no break after fnsi allows the code to be executed whenever there is a match - so that if the element has, f.i., class1 and class2, both fn1 and fn2 will be executed.
    • The advantage of this approach is that the code to execute for each class is arbitrary, like the one in the switch statement; in your example all the cases performed a similar operation, but tomorrow you may need to do different things for each.
    • You may simulate the default case by having a status variable telling whether a match was found in the loop or not.

I think that perfect solution will be this

if ($(this).hasClass("your_Class")) 
    alert("positive");            
else              
    alert("Negative");

Here is a little snippet If you’re trying to check wether element contains a class, without using jQuery.

function hasClass(element, className) {
    return element.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className);
}

This accounts for the fact that element might contain multiple class names separated by space.

OR


You can also assign this function to element prototype.

Element.prototype.hasClass = function(className) {
    return this.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(this.className);
};

And trigger it like this (very similar to jQuery’s .hasClass() function):

document.getElementById('MyDiv').hasClass('active');

For me the most elegant and faster way to achieve it is:

function hasClass(el,cl){
   return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}

As the accepted answer suggests, Element.className returns a string, so you can easily check if a class exists by using the indexOf() method:

element.className.indexOf('animated') > -1

If you are interested in the performance difference between indexOf vs classList.contains, using indexOf seems to be slightly faster. I did a quick benchmark performance test to check that. Here are my findings: ClassName.indexOf vs ClassList.contains.


Try this one:

document.getElementsByClassName = function(cl) {
   var retnode = [];
   var myclass = new RegExp('\\b'+cl+'\\b');
   var elem = this.getElementsByTagName('*');
   for (var i = 0; i < elem.length; i++) {
       var classes = elem[i].className;
       if (myclass.test(classes)) retnode.push(elem[i]);
   }
    return retnode;
};

To check if an element contains a class, you use the contains() method of the classList property of the element:*

element.classList.contains(className);

*Suppose you have the following element:

<div class="secondary info">Item</div>*

To check if the element contains the secondary class, you use the following code:

 const div = document.querySelector('div');
 div.classList.contains('secondary'); // true

The following returns false because the element doesn’t have the class error:

 const div = document.querySelector('div');
 div.classList.contains('error'); // false

This is supported on IE8+.

First we check if classList exists if it does we can use the contains method which is supported by IE10+. If we are on IE9 or 8 it falls back to using a regex, which is not as efficient but is a concise polyfill.

if (el.classList) {
  el.classList.contains(className);
} else {
  new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
}

Alternatively if you are compiling with babel you can simply use: el.classList.contains(className);


Since .className is a string, you can use the string includes() method to check if your .className includes your class name:

element.className.includes("class1")

Element.matches()

element.matches(selectorString)

According to MDN Web Docs:

The Element.matches() method returns true if the element would be selected by the specified selector string; otherwise, returns false.

Therefore, you can use Element.matches() to determine if an element contains a class.

_x000D_
_x000D_
const element = document.querySelector('#example');

console.log(element.matches('.foo')); // true
_x000D_
<div id="example" class="foo bar"></div>
_x000D_
_x000D_
_x000D_

View Browser Compatibility


See this Codepen link for faster and easy way of checking an element if it has a specific class using vanilla JavaScript~!

hasClass (Vanilla JS)

function hasClass(element, cls) {
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}

This is a little old, but maybe someone will find my solution helpfull:

// Fix IE's indexOf Array
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement) {
        if (this == null) throw new TypeError();
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) return -1;
        var n = 0;
        if (arguments.length > 0) {
            n = Number(arguments[1]);
            if (n != n) n = 0;
            else if (n != 0 && n != Infinity && n != -Infinity) n = (n > 0 || -1) * Math.floor(Math.abs(n));
        }
        if (n >= len) return -1;
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) if (k in t && t[k] === searchElement) return k;
        return -1;
    }
}
// add hasClass support
if (!Element.prototype.hasClass) {
    Element.prototype.hasClass = function (classname) {
        if (this == null) throw new TypeError();
        return this.className.split(' ').indexOf(classname) === -1 ? false : true;
    }
}

I created these functions for my website, I use only vanilla javascript, maybe it will help someone. First I created a function to get any HTML element:

//return an HTML element by ID, class or tag name
    var getElement = function(selector) {
        var elements = [];
        if(selector[0] == '#') {
            elements.push(document.getElementById(selector.substring(1, selector.length)));
        } else if(selector[0] == '.') {
            elements = document.getElementsByClassName(selector.substring(1, selector.length));
        } else {
            elements = document.getElementsByTagName(selector);
        }
        return elements;
    }

Then the function that recieve the class to remove and the selector of the element:

var hasClass = function(selector, _class) {
        var elements = getElement(selector);
        var contains = false;
        for (let index = 0; index < elements.length; index++) {
            const curElement = elements[index];
            if(curElement.classList.contains(_class)) {
                contains = true;
                break;
            }
        }
        return contains;
    }

Now you can use it like this:

hasClass('body', 'gray')
hasClass('#like', 'green')
hasClass('.button', 'active')

Hope it will help.


Here's a case-insensitive trivial solution:

function hasClass(element, classNameToTestFor) {
    var classNames = element.className.split(' ');
    for (var i = 0; i < classNames.length; i++) {
        if (classNames[i].toLowerCase() == classNameToTestFor.toLowerCase()) {
            return true;
        }
    }
    return false;
}

The easy and effective solution is trying .contains method.

test.classList.contains(testClass);

A simplified oneliner:1

function hasClassName(classname,id) {
 return  String ( ( document.getElementById(id)||{} ) .className )
         .split(/\s/)
         .indexOf(classname) >= 0;
}

1 indexOf for arrays is not supported by IE (ofcourse). There are plenty of monkey patches to be found on the net for that.


I know there a lot of answers but most of these are for additional functions and additional classes. This is the one I personally use; much cleaner and much less lines of code!

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}

Just to add to the answer for people trying to find class names within inline SVG elements.

Change the hasCLass() function to:

function hasClass(element, cls) {
    return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + cls + ' ') > -1;
  }

Instead of using the className property you'll need to use the getAttribute() method to grab the class name.


Using the classList is also ideal

HTML

<div id="box" class="myClass"></div>

JavaScript

const element = document.querySelector("#box");

element.classList.contains("myClass");

I would Poly fill the classList functionality and use the new syntax. This way newer browser will use the new implementation (which is much faster) and only old browsers will take the performance hit from the code.

https://github.com/remy/polyfills/blob/master/classList.js


In modern browsers, you can just use the contains method of Element.classList :

testElement.classList.contains(className)

Demo

_x000D_
_x000D_
var testElement = document.getElementById('test');

console.log({
    'main' : testElement.classList.contains('main'),
    'cont' : testElement.classList.contains('cont'),
    'content' : testElement.classList.contains('content'),
    'main-cont' : testElement.classList.contains('main-cont'),
    'main-content' : testElement.classList.contains('main-content')
});
_x000D_
<div id="test" class="main main-content content"></div>
_x000D_
_x000D_
_x000D_


Supported browsers

enter image description here

(from CanIUse.com)


Polyfill

If you want to use Element.classList but you also want to support older browsers, consider using this polyfill by Eli Grey.


This is a bit off, but if you have an event that triggers switch, you can do without classes:

<div id="classOne1"></div>
<div id="classOne2"></div>
<div id="classTwo3"></div>

You can do

$('body').click( function() {

    switch ( this.id.replace(/[0-9]/g, '') ) {
        case 'classOne': this.innerHTML = "I have classOne"; break;
        case 'classTwo': this.innerHTML = "I have classTwo"; break;
        default: this.innerHTML = "";
    }

});

.replace(/[0-9]/g, '') removes digits from id.

It is a bit hacky, but works for long switches without extra functions or loops


I've created a prototype method which uses classList, if possible, else resorts to indexOf:

_x000D_
_x000D_
Element.prototype.hasClass = Element.prototype.hasClass || _x000D_
  function(classArr){_x000D_
    var hasClass = 0,_x000D_
        className = this.getAttribute('class');_x000D_
  _x000D_
    if( this == null || !classArr || !className ) return false;_x000D_
  _x000D_
    if( !(classArr instanceof Array) )_x000D_
      classArr = classArr.split(' ');_x000D_
_x000D_
    for( var i in classArr )_x000D_
      // this.classList.contains(classArr[i]) // for modern browsers_x000D_
      if( className.split(classArr[i]).length > 1 )  _x000D_
          hasClass++;_x000D_
_x000D_
    return hasClass == classArr.length;_x000D_
};_x000D_
_x000D_
_x000D_
///////////////////////////////_x000D_
// TESTS (see browser's console when inspecting the output)_x000D_
_x000D_
var elm1 = document.querySelector('p');_x000D_
var elm2 = document.querySelector('b');_x000D_
var elm3 = elm1.firstChild; // textNode_x000D_
var elm4 = document.querySelector('text'); // SVG text_x000D_
_x000D_
console.log( elm1, ' has class "a": ', elm1.hasClass('a') );_x000D_
console.log( elm1, ' has class "b": ', elm1.hasClass('b') );_x000D_
console.log( elm1, ' has class "c": ', elm1.hasClass('c') );_x000D_
console.log( elm1, ' has class "d": ', elm1.hasClass('d') );_x000D_
console.log( elm1, ' has class "a c": ', elm1.hasClass('a c') );_x000D_
console.log( elm1, ' has class "a d": ', elm1.hasClass('a d') );_x000D_
console.log( elm1, ' has class "": ', elm1.hasClass('') );_x000D_
_x000D_
console.log( elm2, ' has class "a": ', elm2.hasClass('a') );_x000D_
_x000D_
// console.log( elm3, ' has class "a": ', elm3.hasClass('a') );_x000D_
_x000D_
console.log( elm4, ' has class "a": ', elm4.hasClass('a') );
_x000D_
<p class='a b c'>This is a <b>test</b> string</p>_x000D_
<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="50px">_x000D_
    <text x="10" y="20" class='a'>SVG Text Example</text>_x000D_
</svg>
_x000D_
_x000D_
_x000D_

Test page


in which element is currently the class '.bar' ? Here is another solution but it's up to you.

var reg = /Image/g, // regexp for an image element
query = document.querySelector('.bar'); // returns [object HTMLImageElement]
query += this.toString(); // turns object into a string

if (query.match(reg)) { // checks if it matches
  alert('the class .bar is attached to the following Element:\n' + query);
}

jsfiddle demo

Of course this is only a lookup for 1 simple element <img>(/Image/g) but you can put all in an array like <li> is /LI/g, <ul> = /UL/g etc.


Since he wants to use switch(), I'm surprised no one has put this forth yet:

var test = document.getElementById("test");
var testClasses = test.className.split(" ");
test.innerHTML = "";
for(var i=0; i<testClasses.length; i++) {
    switch(testClasses[i]) {
        case "class1": test.innerHTML += "I have class1<br/>"; break;
        case "class2": test.innerHTML += "I have class2<br/>"; break;
        case "class3": test.innerHTML += "I have class3<br/>"; break;
        case "class4": test.innerHTML += "I have class4<br/>"; break;
        default: test.innerHTML += "(unknown class:" + testClasses[i] + ")<br/>";
    }
}

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to dom

How do you set the document title in React? How to find if element with specific id exists or not Cannot read property 'style' of undefined -- Uncaught Type Error adding text to an existing text element in javascript via DOM Violation Long running JavaScript task took xx ms How to get `DOM Element` in Angular 2? Angular2, what is the correct way to disable an anchor element? React.js: How to append a component on click? Detect click outside React component DOM element to corresponding vue.js component