JQuery .hasClass for multiple values in an if statement

110,341

Solution 1

You just had some messed up parentheses in your 2nd attempt.

var $html = $("html");

if ($html.hasClass('m320') || $html.hasClass('m768')) {

  // do stuff 

}

Solution 2

You could use is() instead of hasClass():

if ($('html').is('.m320, .m768')) { ... }

Solution 3

For fun, I wrote a little jQuery add-on method that will check for any one of multiple class names:

$.fn.hasAnyClass = function() {
    for (var i = 0; i < arguments.length; i++) {
        if (this.hasClass(arguments[i])) {
            return true;
        }
    }
    return false;
}

Then, in your example, you could use this:

if ($('html').hasAnyClass('m320', 'm768')) {

// do stuff 

}

You can pass as many class names as you want.


Here's an enhanced version that also lets you pass multiple class names separated by a space:

$.fn.hasAnyClass = function() {
    for (var i = 0; i < arguments.length; i++) {
        var classes = arguments[i].split(" ");
        for (var j = 0; j < classes.length; j++) {
            if (this.hasClass(classes[j])) {
                return true;
            }
        }
    }
    return false;
}

if ($('html').hasAnyClass('m320 m768')) {
    // do stuff 
}

Working demo: http://jsfiddle.net/jfriend00/uvtSA/

Solution 4

This may be another solution:

if ($('html').attr('class').match(/m320|m768/)) {  
  // do stuff   
}  

according to jsperf.com it's quite fast, too.

Solution 5

For anyone wondering about some of the different performance aspects with all of these different options, I've created a jsperf case here: jsperf

In short, using element.hasClass('class') is the fastest.

Next best bet is using elem.hasClass('classA') || elem.hasClass('classB'). A note on this one: order matters! If the class 'classA' is more likely to be found, list it first! OR condition statements return as soon as one of them is met.

The worst performance by far was using element.is('.class').

Also listed in the jsperf is CyberMonk's function, and Kolja's solution.

Share:
110,341

Related videos on Youtube

Danny Englander
Author by

Danny Englander

I'm a Drupal themer, developer &amp; evangelist. I love to blog about and engage in the Drupal community.

Updated on September 23, 2020

Comments

  • Danny Englander
    Danny Englander over 3 years

    I have a simple if statement as such:

    if ($('html').hasClass('m320')) {
    
    // do stuff 
    
    }
    

    This works as expected. However, I want to add more classes to the if statement to check if any of the classes are present in the <html> tag. I need it so it's not all of them but just the presence of at least one class but it can be more.

    My use case is that I have classes (e.g. m320, m768) added for various viewport widths so I only want to execute certain Jquery if it's a specific width (class).

    Here is what i have tried so far:

    1.

    if ($('html').hasClass('m320', 'm768')) {
    
    // do stuff 
    
    }
    

    2.

    if ($('html').hasClass('m320')) || ($('html').hasClass('m768')) {
    
     // do stuff 
    
    }
    

    3.

     if ($('html').hasClass(['m320', 'm768'])) {
    
     // do stuff 
    
        }
    

    None of these seem to work though. Not sure what I am doing wrong but most likely my syntax or structure.

  • elclanrs
    elclanrs almost 12 years
    Yeah hasClass() is probably faster but is() is way more convenient most of the time
  • James Montagne
    James Montagne almost 12 years
    If you're going to do that, why even bother using jquery to get the element?
  • adeneo
    adeneo almost 12 years
    Well I would'nt, but at least it only gets the classes once? It just seemed so dull without a little jQuery, so I replaced getElementsByTagName with some jQ magic just for you!
  • epascarello
    epascarello almost 12 years
    You really should cache $('html') into a variable instead of having to look it up multiple times.
  • James Montagne
    James Montagne almost 12 years
    @epascarello Very true, updating the answer for posterity.
  • crmpicco
    crmpicco over 11 years
    Excellent, this works well...cross-browser too! Tested on FF and IE.
  • CyberMonk
    CyberMonk about 11 years
    I made a slight mod to make it conform to the jQuery conventions for .addClass and .removeClass(). (stackoverflow.com/a/14887517/170456)
  • Danny Englander
    Danny Englander over 10 years
    Really interesting! I had no idea about jsperf. Thanks for illustrating all the different variations.
  • Philip
    Philip over 9 years
    Very nice, much faster!
  • Juan Lanus
    Juan Lanus over 9 years
    This will match also class 'ZZZm320WWW' and the like. Try ...match(/\b(m320|m768)\b/) where the \b's match the beginning and the end of a word.
  • Heretic Monkey
    Heretic Monkey over 7 years
    Welcome to Stack Overflow! Please add some explanation of why this code helps the OP. This will help provide an answer future viewers can learn from. See How to Answer for more information.
  • Jignesh Gohel
    Jignesh Gohel over 5 years
    BTW here we can see the performance benchmarks for is() and hasClass()
  • jerclarke
    jerclarke over 5 years
    So it's a lot slower, but also super fast overall. If there's only a few items being scanned, seems like not a big deal for much cleaner code.
  • Sanya
    Sanya almost 4 years
    just to follow up (7 years later :) ). This works great but if the html element you define does not have any classes - it will shoot a 'Cannot read property "match" of undefined' error. If this is the case, test if the element even has the 'class' attribute (or test to make sure the attribute 'class' is not null).
  • MightyPork
    MightyPork over 3 years
    This is wrong. The first example you gave works just because the method has poor sanitization of input and thinks the whole string is a class name. It does not work if the classes are in a different order, or not right next to each other. See example: jsfiddle.net/0d57ekty
  • qwerty_igor
    qwerty_igor over 3 years
    @MightyPork thanks for checking. you're right, it should only be used per class
  • NinoMarconi
    NinoMarconi over 2 years
    Info: "is" matches class a OR b, "hasClass" matches class a AND b