489

How do you do jQuery’s hasClass with plain ol’ JavaScript? For example,

<body class="foo thatClass bar">

What’s the JavaScript way to ask if <body> has thatClass?

2
  • I suppose you would have to parse the class property (which in case of multiple classes will have multiple class names in random order separated by a space) and check whether your class name is in it. Not terribly difficult, but still terribly inconvenient if not for learning purposes :) Commented Feb 23, 2011 at 0:06
  • 13
    don't know if I'm late for the party but a good site that gives alternatives to jQuery functions is youmightnotneedjquery.com Commented Jun 26, 2014 at 7:59

14 Answers 14

1503

Simply use classList.contains():

if (document.body.classList.contains('thatClass')) {
    // do some stuff
}

Other uses of classList:

document.body.classList.add('thisClass');
// $('body').addClass('thisClass');

document.body.classList.remove('thatClass');
// $('body').removeClass('thatClass');

document.body.classList.toggle('anotherClass');
// $('body').toggleClass('anotherClass');

Browser Support:

  • Chrome 8.0
  • Firefox 3.6
  • IE 10
  • Opera 11.50
  • Safari 5.1

classList Browser Support

Sign up to request clarification or add additional context in comments.

5 Comments

This is unsupported in IE8. IE8 can retrieve .classList as a string, but it will not recognise the more modern methods such as .classList.contains()
@iono In the Element.classList implementation description from the MDN there is a shim that extend the support to this behavior to IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
I agree with @AlexanderWigmore, this was incredibly helpful and simple.
This should be the acceptable answer since 2020. As no one talk about IE8 / WinXP anymore.
Agree. .. IE8 is dead. IE in general is dead. This should be the way moving forward.
118

You can check whether element.className matches /\bthatClass\b/.
\b matches a word break.

Or, you can use jQuery's own implementation:

var className = " " + selector + " ";
if ( (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(" thatClass ") > -1 ) 

To answer your more general question, you can look at jQuery's source code on github or at the source for hasClass specifically in this source viewer.

7 Comments

+1 for jQuery implementation (of for having looked up (is this proper English?) what rclass actually is ;))
Wouldn't \b match "thatClass-anotherClass"?
just for completeness: rclass in recent versions is "/[\n\t\r]/g" (\r added)
@FelixSchwarz is right, in current jQuery the regexp was updated to /[\t\r\n\f]/g. Also it's good to mention that /\bclass\b/ can fail for classnames with - minus sign (other than that it works good) , that's why jQuery's implementation is better and more reliable. For example: /\bbig\b/.test('big-text') returns true instead of expected false.
How did this discussion turn into jQuery when the original question was asking for a non-jQuery implementation?
|
36

The most effective one liner that

  • returns a boolean (as opposed to Orbling's answer)
  • Does not return a false positive when searching for thisClass on an element that has class="thisClass-suffix".
  • is compatible with every browser down to at least IE6

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

Comments

34

// 1. Use if for see that classes:

if (document.querySelector(".section-name").classList.contains("section-filter")) {
  alert("Grid section");
  // code...
}
<!--2. Add a class in the .html:-->

<div class="section-name section-filter">...</div>

4 Comments

@greg_diesel: do not discourage answers! New solutions for common problems are more than welcome.
@Raveren while new solutions to old problems are welcomed, this particular answer brings nothing new. It only adds noise to this question.
@raveren This isn't a new solution, it's the same as this answer but with less information.
new solution = not noise... this new solution = perfect answer for me... this is why "do not discourage new solutions" comment was made...
33

The attribute that stores the classes in use is className.

So you can say:

if (document.body.className.match(/\bmyclass\b/)) {
    ....
}

If you want a location that shows you how jQuery does everything, I would suggest:

http://code.jquery.com/jquery-1.5.js

4 Comments

Excellent. The match attribute comes handy again! Does really jQuery does something more than is possible in JavaScript?! If not, jQuery is just an unnecessary weight of shorthands.
This also matches myclass-something, as \b matches hyphen.
@animaacija All javascript libraries/plugins are basically javascript shorthands because they are build with javascript. Thing is: Shorthands are always necessary. Never reinvent the wheel.
I think classList.contains('className') is a better solution than this. Avoid the generalizations Edwin. You should stop using so much words such as "always" and "never"
23

Element.matches()

Instead of $(element).hasClass('example') in jQuery, you can use element.matches('.example') in plain JavaScript:

if (element.matches('.example')) {
  // Element has example class ...
}

View Browser Compatibility

3 Comments

hasClass drop-in w/ es6... hasClass = (el, name) => el.matches('.'+name) ? 1 : 0
should be the top answer.
Indeed shortest, but probably slower (measurethat.net/Benchmarks/Show/7742/0/…).
13

hasClass function:

HTMLElement.prototype.hasClass = function(cls) {
    var i;
    var classes = this.className.split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] == cls) {
            return true;
        }
    }
    return false;
};

addClass function:

HTMLElement.prototype.addClass = function(add) {
    if (!this.hasClass(add)){
        this.className = (this.className + " " + add).trim();
    }
};

removeClass function:

HTMLElement.prototype.removeClass = function(remove) {
    var newClassName = "";
    var i;
    var classes = this.className.replace(/\s{2,}/g, ' ').split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] !== remove) {
            newClassName += classes[i] + " ";
        }
    }
    this.className = newClassName.trim();
};

Comments

11

I use a simple/minimal solution, one line, cross browser, and works with legacy browsers as well:

/\bmyClass/.test(document.body.className) // notice the \b command for whole word 'myClass'

This method is great because does not require polyfills and if you use them for classList it's much better in terms of performance. At least for me.

Update: I made a tiny polyfill that's an all round solution I use now:

function hasClass(element,testClass){
  if ('classList' in element) { return element.classList.contains(testClass);
} else { return new Regexp(testClass).exec(element.className); } // this is better

//} else { return el.className.indexOf(testClass) != -1; } // this is faster but requires indexOf() polyfill
  return false;
}

For the other class manipulation, see the complete file here.

7 Comments

Will this trip over a class of notmyClassHere?
You can also ask if your class isn't there as well !/myClass/.test(document.body.className) notice the ! symbol.
I'm not talking about negating the question. I'm thinking that your function will improperly return true if the class name is thisIsmyClassHere.
I was only guessing that's what you ask about, didn't understand exactly what you need, but have you tried it and it failed returning true/false as it should?
This is not perfect as it is not substrings proof. E.g. when document.body.className = 'myClass123', then /myClass/.test(document.body.className) return true...
|
10

This 'hasClass' function works in IE8+, FireFox and Chrome:

hasClass = function(el, cls) {
    var regexp = new RegExp('(\\s|^)' + cls + '(\\s|$)'),
        target = (typeof el.className === 'undefined') ? window.event.srcElement : el;
    return target.className.match(regexp);
}

[Updated Jan'2021] A better way:

hasClass = (el, cls) => {
  [...el.classList].includes(cls); //cls without dot
};

3 Comments

Better: [...el.classList].includes(cls); //cls without dot
I think you meant [...el.classList].contains(cls); for the 2021 update, right?
Node.contains is used for childnodes. With [... ] it converts the DOMTokenList into an Array of the node's classes. To search into an array I use includes
9

a good solution for this is to work with classList and contains.

i did it like this:

... for ( var i = 0; i < container.length; i++ ) {
        if ( container[i].classList.contains('half_width') ) { ...

So you need your element and check the list of the classes. If one of the classes is the same as the one you search for it will return true if not it will return false!

Comments

6

Use something like:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');

3 Comments

Isn't this equivalent to myHTMLSelector.classList.indexOf('the-class')? Don't you also want >=0 at the end?
What's the point of using [].indexOf if classList has a contains method?
@Teepeemm no. myHTMLSelector.classList.indexOf('the-class') returns the error that myHTMLSelector.classList.indexOf is not a function because myHTMLSelector.classList is not an array. But I guess when calling it using Array.prototype some conversion happens. This may support older browser, though contains has very good support.
6
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}

Comments

1

Well all of the above answers are pretty good but here is a small simple function I whipped up. It works pretty well.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}

1 Comment

What's the point of iterating if classList has a contains method?
1

What do you think about this approach?

<body class="thatClass anotherClass"> </body>

var bodyClasses = document.querySelector('body').className;
var myClass = new RegExp("thatClass");
var trueOrFalse = myClass.test( bodyClasses );

https://jsfiddle.net/5sv30bhe/

1 Comment

I think you're mixing your variable names (active===myClass?). But won't this approach give a false positive for class="nothatClassIsnt"?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.