jQuery hasClass () - recherche plus d'une classe

162

Avec:

if(element.hasClass("class"))

Je peux rechercher une classe, mais y a-t-il un moyen simple de vérifier si "élément" a l'une des nombreuses classes?

J'utilise:

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

Ce qui n'est pas trop mal, mais je pense à quelque chose comme:

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

Ce qui ne fonctionne malheureusement pas.

Y a-t-il quelque chose comme ça?

Hans
la source

Réponses:

228

Que diriez-vous:

element.is('.class1, .class2')
Matchu
la source
9
Non, car cela rechercherait des éléments qui ont les deux classes. Je pense que Marcel recherche des éléments avec une ou plusieurs classes.
Giles Van Gruisen
Je viens de remarquer que j'ai 4 éléments id = "hello". Version corrigée pour faire plaisir aux validateurs: jsbin.com/uqoku/2/edit
Matchu
1
@Matchu J'avais le même problème avec .hasClass()mais votre solution semble avoir fait l'affaire, merci
Nasir
11
Cela n'a pas fonctionné pour moi, mais a $('element').is('.class1.class2')fait
iamchriswick
6
@iamchriswick: C'est légèrement différent de ce que OP demandait. .class1.class2correspondra aux éléments qui ont les deux classes, mais ils recherchaient des éléments correspondant à l'une ou l'autre des classes.
Matchu
291
element.is('.class1, .class2')

fonctionne, mais c'est 35% plus lent que

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

entrez la description de l'image ici

Si vous doutez de ce que je dis, vous pouvez vérifier sur jsperf.com .

J'espère que cela aidera quelqu'un.

Simon Arnold
la source
16
19% plus lent, gros problème. Les programmeurs sont plus chers.
Nowaker
21
@DamianNowak si ces programmeurs ne sont pas prêts à écrire ce qui équivaut à une quantité insignifiante de code supplémentaire, ils ne sont probablement pas très chers.
Akkuma
2
... euh, mais je viens de l'exécuter dans jsperf pour Chrome 21.0.1180 et la méthode is () est maintenant environ 20% plus rapide. Mais hasClass () semble plus lisible.
Danyal Aytekin
3
@psychobrm: Si vous devez vérifier 10 classes à la fois, ce dont vous avez vraiment besoin est de rationaliser les noms de vos classes. Il n'y a aucune raison pour de telles absurdités. :)
cHao
5
Personnellement, je ne vois pas la nécessité d'optimiser les performances. 12000 opérations par seconde me semblent assez rapides. Je dirais d'utiliser ce qui vous convient le mieux. Optimisez les performances lorsque le besoin s'en fait sentir.
3Dom
38
$.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']);

Cela devrait le faire, simple et facile.

Kalel Wade
la source
2
Il vous manque un var dans le for (i dans les sélecteurs), créant ainsi un fichier global.
gremwell
4
Un petit point mineur, mais les sélecteurs de paramètres devraient vraiment être nommés classes ou classNames , car c'est ce que vous passez, pas des sélecteurs. Les sélecteurs auraient un point devant eux, comme dans $ ('# element'). HasClasses (['. Class1', '.class2', '.class3']);
jbyrd
10

filter () est une autre option

Réduisez l'ensemble des éléments correspondants à ceux qui correspondent au sélecteur ou réussissent le test de la fonction.

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

$(selector).filter('.class1.class2'); // Filter elements: class1 AND class2
John Magnolia
la source
6

Que dis-tu de ça?

if (element.hasClass("class1 class2")
Robert Łoziński
la source
3
Cela ne fonctionne pas si vous recherchez une condition OR.
Jason Conville
4

voici une réponse qui suit la syntaxe de

$(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);

ce n'est pas le plus rapide, mais c'est sans ambiguïté et la solution que je préfère. banc: http://jsperf.com/hasclasstest/10

Henrik Myntti
la source
Error: $self is not defined
bagofmilk
1
@bagofmilk Ma réponse a été éditée par d'autres depuis que je l'ai écrite il y a 6 ans. Comme je n'ai pas utilisé jQuery depuis des années, je ne sais pas exactement ce qui était prévu avec l'édition mais à l'origine je l'avais var $self = $(this);juste avant la boucle for
Henrik Myntti
1

Et ça,

$.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;
    }
});

Facile à utiliser,

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

Et cela semble être plus rapide, http://jsperf.com/hasclasstest/7

Okan Kocyigit
la source
1

Qu'en est-il de:

if($('.class.class2.class3').length > 0){
    //...
}
u01jmg3
la source
3
Vous n'avez pas besoin du > 0. Si la longueur est différente de zéro, elle retournera vrai.
Isaac Lubow
1

jQuery

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

Vanille JS

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

utilisez la fonction js match () par défaut:

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

pour utiliser des variables dans l'expression rationnelle, utilisez ceci:

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

au fait, c'est le moyen le plus rapide: http://jsperf.com/hasclass-vs-is-stackoverflow/22

Romualds Cirsis
la source
J'aime mieux cette réponse, même si je soupçonne que parcourir les classes et utiliser une chaîne de test indexOf pourrait être encore plus rapide ...
terraling
0

Travaille pour moi:

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

 //do something here

 }
Rangel R. Morais
la source
0

Vous pouvez faire de cette façon:

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

if($(selector).filter('.class1, .class2').length){
    // And logic
}
Hamidreza
la source
-1

Cela a fonctionné pour moi:

$('.class1[class~="class2"]').append('something');
Tina
la source
3
Cette réponse n'a rien à voir avec la question posée.
Jezen Thomas
C'est en fait une excellente réponse. La syntaxe du sélecteur ci-dessus saisit tous les éléments avec à la fois class1 et class2. Ensuite, vous pouvez en faire ce que vous voulez, dans ce cas, ajoutez. Je n'ai pas vérifié les performances par rapport aux autres méthodes, mais la syntaxe est agréable et succincte.
Tim Wright
2
@TimWright C'est une réponse terrible. La manière normale de sélectionner un élément avec 2 classes est $('.class1.class2')sans avoir besoin d'utiliser un sélecteur d'attribut pour la deuxième classe. En outre, la question est de savoir comment sélectionner un élément par l'une des classes, pas toutes.
Tous les travailleurs sont essentiels