jQuery hasClass() - check for more than one class

JqueryPerformanceJquery Selectors

Jquery Problem Overview


With:

if(element.hasClass("class"))

I can check for one class, but is there an easy way to check whether "element" has any of many classes?

I am using:

if(element.hasClass("class") || element.hasClass("class") ... )

Which isn't too bad, but I am thinking of something like:

if(element.hasClass("class", "class2")

Which unfortunately doesn't work.

Is there something like that?

Jquery Solutions


Solution 1 - Jquery

element.is('.class1, .class2')

works, but it's 35% slower than

element.hasClass('class1') || element.hasClass('class2')

JSperf chart showing .hasClass() is faster than .is()

See also this jsbench.me test.

Solution 2 - Jquery

How about:

element.is('.class1, .class2')

Solution 3 - Jquery

$.fn.extend({
    hasClasses: function (selectors) {
        var self = this;
        for (var i in selectors) {
            if ($(self).hasClass(selectors[i])) 
                return true;
        }
        return false;
    }
});

$('#element').hasClasses(['class1', 'class2', 'class3']);

This should do it, simple and easy.

Solution 4 - Jquery

filter() is another option

> Reduce the set of matched elements to those that match the selector or > pass the function's test.

$(selector).filter('.class1, .class2'); //Filter elements: class1 OR class2

$(selector).filter('.class1.class2'); // Filter elements: class1 AND class2

Solution 5 - Jquery

How about this?

if (element.hasClass("class1 class2")

Solution 6 - Jquery

here's an answer that does follow the syntax of

$(element).hasAnyOfClasses("class1","class2","class3")

(function($){
    $.fn.hasAnyOfClasses = function(){
		for(var i= 0, il=arguments.length; i<il; i++){
			if($self.hasClass(arguments[i])) return true;
		}
		return false;
	}
})(jQuery);

it's not the fastest, but its unambiguous and the solution i prefer. bench: http://jsperf.com/hasclasstest/10

Solution 7 - Jquery

What about:

if ($('.class.class2.class3').length) {
    //...
}

Solution 8 - Jquery

jQuery

if( ['class', 'class2'].some(c => [...element[0].classList].includes(c)) )

Vanilla JS

if( ['class', 'class2'].some(c => [...element.classList].includes(c)) )

Solution 9 - Jquery

What about this,

$.fn.extend({
     hasClasses: function( selector ) {
		var classNamesRegex = new RegExp("( " + selector.replace(/ +/g,"").replace(/,/g, " | ") + " )"),
			rclass = /[\n\t\r]/g,
            i = 0,
			l = this.length;
		for ( ; i < l; i++ ) {
			if ( this[i].nodeType === 1 && classNamesRegex.test((" " + this[i].className + " ").replace(rclass, " "))) {
				return true;
			}
		}
		return false;
	}
});

Easy to use,

if ( $("selector").hasClasses("class1, class2, class3") ) {
  //Yes It does
}

And It seems to be faster, http://jsperf.com/hasclasstest/7

Solution 10 - Jquery

This is quite old, but hear me out on this one.

$.fn.extend({
  hasClasses: function (selectors) {
      // Setup
      const _id = $(this).attr('id'); // Preserve existing id
      const uuid = generateUUID();    // Create new id for query
      $(this).attr('id', uuid);       // Apply new id to element
     
      // Query to find if element has any of the classes
      const res = selectors.some(cls => !!$(`${uuid}.${cls}`).length);
      
      // Rollback on id	
      if (!_id) $(this).removeAttr("id"); // No Id to begin with
      else $(this).attr('id', _id);       // Preserve old id
      
      // Done
      return res;
    }
})

Instead of trying to find a match between one of the classes in selectors and one of the element's classes we simply apply a temporary id (uuid) to the element and query to find if there exists some element with that temporary id and any of the classes listed in selectors.

This inspired by Kalel Wade's and Simon Arnold's solution but with a minor improvement to performance (benchmarked on jsbench.me).

Note

JSBENCH doesn't allow saving over a limit of a certain amount of characters or words. I had some trouble with the async fetching of random words, so you can get random words manually and use the bench that way.

EDIT:

I just noticed that for my implementation of this I am relying on the id with async calls. I might cause an issue if I need to query the element by id the same time that hasClasses changes the id.

To circumvent this we can just add a unique uuid attribute (literally just the uuid).

Here is the correction:

$.fn.extend({
  hasClasses: function (selectors) {
    // Setup
    const uuid = generateUUID(); // Create new uuid to query later
    $(this).attr(uuid, "");      // Apply uuid to element for query

    // Query to find if element has any of the classes
    const res = selectors.some(cls => !!$(`[${uuid}].${cls}`).length);

    // Remove the uuid attribute
    $(this).removeAttr(uuid);

    // Done
    return res;
  }
})

We could still use an the elements' id if it has one instead of adding an attribute.
I'm not sure if querying ids is faster or not. I referenced this, but by the looks of it there isn't much of a hit with modern browsers. Could still implement using the id if it exists instead of an attribute.

Solution 11 - Jquery

use default js match() function:

if( element.attr('class') !== undefined && element.attr('class').match(/class1|class2|class3|class4|class5/) ) {
  console.log("match");
}

to use variables in regexp, use this:

var reg = new RegExp(variable, 'g');
$(this).match(reg);

by the way, this is the fastest way: http://jsperf.com/hasclass-vs-is-stackoverflow/22

Solution 12 - Jquery

You can do this way:

if($(selector).filter('.class1, .class2').length){
    // Or logic
}

if($(selector).filter('.class1.class2').length){
    // And logic
}

Solution 13 - Jquery

This worked for me:

$('.class1[class~="class2"]').append('something');

Solution 14 - Jquery

Works for me:

 if ( $("element").hasClass( "class1") || $("element").hasClass("class2") ) {

 //do something here

 }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBj&#246;rnView Question on Stackoverflow
Solution 1 - JquerySimon ArnoldView Answer on Stackoverflow
Solution 2 - JqueryMatchuView Answer on Stackoverflow
Solution 3 - JqueryKalel WadeView Answer on Stackoverflow
Solution 4 - JqueryJohn MagnoliaView Answer on Stackoverflow
Solution 5 - JqueryRobert ŁozińskiView Answer on Stackoverflow
Solution 6 - JqueryHenrik MynttiView Answer on Stackoverflow
Solution 7 - Jqueryu01jmg3View Answer on Stackoverflow
Solution 8 - JquerySimon ArnoldView Answer on Stackoverflow
Solution 9 - JqueryOkan KocyigitView Answer on Stackoverflow
Solution 10 - Jquerysource144View Answer on Stackoverflow
Solution 11 - JqueryRomualds CirsisView Answer on Stackoverflow
Solution 12 - JqueryHamidrezaView Answer on Stackoverflow
Solution 13 - JqueryTinaView Answer on Stackoverflow
Solution 14 - JqueryRangel R. MoraisView Answer on Stackoverflow