462

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?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Kyle Cureau
  • 19,028
  • 23
  • 75
  • 104
  • 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 :) – Pekka Feb 23 '11 at 00:06
  • 13
    don't know if I'm late for the party but a good site that gives alternatives to jQuery functions is http://youmightnotneedjquery.com – ithil Jun 26 '14 at 07:59

14 Answers14

1456

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

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Damien
  • 26,933
  • 7
  • 39
  • 40
  • 5
    **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 Sep 10 '13 at 04:14
  • 7
    @iono In the [Element.classList](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList) implementation description from the MDN there is a shim that extend the support to this behavior to IE8 https://developer.mozilla.org/en-US/docs/Web/API/Element/classList – James Mar 17 '15 at 18:23
  • 4
    I agree with @AlexanderWigmore, this was incredibly helpful and simple. – Jacques Olivier Aug 07 '18 at 09:58
  • 12
    This should be the acceptable answer since 2020. As no one talk about IE8 / WinXP anymore. – Thanh Trung Aug 25 '20 at 10:12
  • 11
    Agree. .. IE8 is dead. IE in general is dead. This should be the way moving forward. – Emmanuel N K Aug 28 '20 at 04:30
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.

Wayne
  • 59,728
  • 15
  • 131
  • 126
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 6
    +1 for jQuery implementation (of for having looked up (is this proper English?) what `rclass` actually is ;)) – Felix Kling Feb 23 '11 at 00:15
  • 7
    Wouldn't `\b` match "thatClass-anotherClass"? – Matthew Crumley Feb 23 '11 at 01:00
  • 4
    just for completeness: rclass in recent versions is "/[\n\t\r]/g" (\r added) – Felix Schwarz Jan 16 '13 at 13:32
  • 5
    @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. – Stano Jun 18 '13 at 18:43
  • How did this discussion turn into jQuery when the original question was asking for a non-jQuery implementation? – David Maness Jul 06 '20 at 16:02
  • what is selector here? – Vikas chhabra Jul 28 '20 at 22:18
  • @DavidManess - often times a "non-jquery" solution involves grabbing the guts of a jquery function so that you don't have to pull in the whole library. This is important because jquery has been battle-tested by millions of users and developers across every imaginable browser. – Ryan Wheale Nov 23 '20 at 19:51
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);
}
raveren
  • 17,799
  • 12
  • 70
  • 83
33

// 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>
az-stive
  • 347
  • 3
  • 5
  • 6
    @greg_diesel: do not discourage answers! New solutions for common problems are more than welcome. – raveren Mar 10 '15 at 08:08
  • 2
    @Raveren while new solutions to old problems are welcomed, this particular answer brings nothing new. It only adds noise to this question. – Emile Bergeron Nov 03 '16 at 21:46
  • 1
    @raveren This isn't a new solution, it's the same as [this answer](https://stackoverflow.com/a/16337545/1863564) but with less information. – Nic May 19 '18 at 22:57
  • new solution = not noise... this new solution = perfect answer for me... this is why "do not discourage new solutions" comment was made... – aequalsb Apr 01 '22 at 09:58
32

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

Orbling
  • 20,413
  • 3
  • 53
  • 64
  • 1
    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. – animaacija Jan 04 '15 at 21:35
  • 1
    This also matches `myclass-something`, as `\b` matches hyphen. – Marc Durdin Jun 04 '15 at 22:20
  • 1
    @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. – Edwin Stoteler Jul 14 '16 at 09:06
  • 1
    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" – wlf Aug 21 '21 at 11:56
18

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

Grant Miller
  • 27,532
  • 16
  • 147
  • 165
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();
};
Gawin
  • 994
  • 10
  • 12
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.

thednp
  • 4,401
  • 4
  • 33
  • 45
  • 2
    Will this trip over a class of `notmyClassHere`? – Teepeemm Oct 04 '15 at 00:00
  • 2
    You can also ask if your class isn't there as well `!/myClass/.test(document.body.className)` notice the `!` symbol. – thednp Oct 04 '15 at 00:56
  • 1
    I'm not talking about negating the question. I'm thinking that your function will improperly return true if the class name is `thisIsmyClassHere`. – Teepeemm Oct 04 '15 at 02:48
  • 1
    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? – thednp Oct 04 '15 at 17:51
  • 2
    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... – Chris W Mar 10 '16 at 19:50
  • In that case you can do some more regex to also handle substrings, in most cases this is so helpful. At least for me. – thednp Mar 10 '16 at 20:47
  • @ZbigniewWiadro I updated the answer to only check words, `/\bmyClass123/` will test exactly that. – thednp May 13 '16 at 16:38
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!

9

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
};
manufosela
  • 469
  • 6
  • 8
6

Use something like:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');
Pang
  • 9,564
  • 146
  • 81
  • 122
Alejandro Nanez
  • 335
  • 2
  • 6
  • 16
  • 3
    Isn't this equivalent to `myHTMLSelector.classList.indexOf('the-class')`? Don't you also want `>=0` at the end? – Teepeemm Oct 03 '15 at 23:58
  • 5
    What's the point of using `[].indexOf` if `classList` has a `contains` method? – Oriol Jun 12 '16 at 17:19
  • @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. – Ehsan88 Mar 06 '20 at 10:28
6
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}
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;
        }
    }
}
j0hnstew
  • 709
  • 8
  • 25
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/

Marian07
  • 2,303
  • 4
  • 27
  • 48
  • 2
    I think you're mixing your variable names (active===myClass?). But won't this approach give a false positive for `class="nothatClassIsnt"`? – Teepeemm Oct 03 '15 at 23:59