87

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.

Danny Englander
  • 2,005
  • 5
  • 26
  • 41
  • 1
    Instead of guessing at how an API works, you should read the docs. http://api.jquery.com/hasclass/ Also, you should have your developer's console handy/open during developement. – cliffs of insanity May 11 '12 at 22:03
  • possible duplicate of [jQuery hasClass() - check for more than one class](http://stackoverflow.com/questions/2214952/jquery-hasclass-check-for-more-than-one-class) – Stephan Weinhold May 08 '15 at 09:10

10 Answers10

174

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

if ($('html').is('.m320, .m768')) { ... }
elclanrs
  • 92,861
  • 21
  • 134
  • 171
77

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

var $html = $("html");

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

  // do stuff 

}
James Montagne
  • 77,516
  • 14
  • 110
  • 130
31

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/

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Excellent, this works well...cross-browser too! Tested on FF and IE. – crmpicco Jan 23 '13 at 16:24
  • I made a slight mod to make it conform to the jQuery conventions for .addClass and .removeClass(). (http://stackoverflow.com/a/14887517/170456) – CyberMonk Feb 15 '13 at 02:36
28

This may be another solution:

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

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

Kolja
  • 2,667
  • 1
  • 30
  • 29
  • Very nice, much faster! – Philip Nov 01 '14 at 13:56
  • 9
    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. – Juan Lanus Nov 11 '14 at 13:15
  • 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). – Sanya Jun 29 '20 at 14:33
6

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.

Community
  • 1
  • 1
Ryan Steffer
  • 425
  • 6
  • 10
3

Here is a slight variation on answer offered by jfriend00:

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

Allows use of same syntax as .addClass() and .removeClass(). e.g., .hasAnyClass('m320 m768') Needs bulletproofing, of course, as it assumes at least one argument.

CyberMonk
  • 1,462
  • 2
  • 16
  • 21
0
var classes = $('html')[0].className;

if (classes.indexOf('m320') != -1 || classes.indexOf('m768') != -1) {
    //do something
}
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • 2
    If you're going to do that, why even bother using jquery to get the element? – James Montagne May 11 '12 at 22:08
  • 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! – adeneo May 11 '12 at 22:17
0

The hasClass method will accept an array of class names as an argument, you can do something like this:

$(document).ready(function() {
function filterFilesList() {
    var rows = $('.file-row');
    var checked = $("#filterControls :checkbox:checked");

    if (checked.length) {
        var criteriaCollection = [];

        checked.each(function() {
            criteriaCollection.push($(this).val());
        });

        rows.each(function() {
            var row = $(this);
            var rowMatch = row.hasClass(criteriaCollection);

            if (rowMatch) {
                row.show();
            } else {
                row.hide(200);
            }
        });
    } else {
        rows.each(function() {
            $(this).show();
        });
    }
}

    $("#filterControls :checkbox").click(filterFilesList);
    filterFilesList();
});
Ron Sims II
  • 566
  • 5
  • 10
0

This is in case you need both classes present. For either or logic just use ||

$('el').hasClass('first-class') || $('el').hasClass('second-class')

Feel free to optimize as needed

qwerty_igor
  • 919
  • 8
  • 14
  • 1
    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: https://jsfiddle.net/0d57ekty/ – MightyPork Sep 22 '20 at 08:17
  • @MightyPork thanks for checking. you're right, it should only be used per class – qwerty_igor Sep 22 '20 at 11:59
-1

Try this:

if ($('html').hasClass('class1 class2')) {

// do stuff 

}
S M
  • 3,133
  • 5
  • 30
  • 59
  • 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 [answer] for more information. – Heretic Monkey Oct 14 '16 at 14:29