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?
The hasClass() method checks if any of the selected elements have a specified class name. If ANY of the selected elements has the specified class name, this method will return "true".
The . class selector can also be used to select multiple classes. Note: Seperate each class with a comma. Note: Do not start a class attribute with a number.
The is( selector ) method checks the current selection against an expression and returns true, if at least one element of the selection fits the given selector. If no element fits, or the selector is not valid, then the response will be 'false'.
jQuery
if( ['class', 'class2'].some(c => [...element[0].classList].includes(c)) )
Vanilla JS
if( ['class', 'class2'].some(c => [...element.classList].includes(c)) )
How about:
element.is('.class1, .class2')
$.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.
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
How about this?
if (element.hasClass("class1 class2")
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
What about:
if ($('.class.class2.class3').length) {
//...
}
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
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).
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.
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 id
s 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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With