jQuery hasClass () - verifique se há mais de uma classe

162

Com:

if(element.hasClass("class"))

Posso verificar uma classe, mas existe uma maneira fácil de verificar se "elemento" tem alguma de muitas classes?

Estou usando:

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

O que não é tão ruim, mas estou pensando em algo como:

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

O que infelizmente não funciona.

Existe algo assim?

Hans
fonte

Respostas:

227

E se:

element.is('.class1, .class2')
Matchu
fonte
9
Não, porque isso procuraria elementos que tenham ambas as classes. Acho que Marcel está procurando elementos com uma ou mais de várias classes.
Giles Van Gruisen
Só agora notei que eu tenho 4 id = "Olá" elementos lá. Versão corrigida para alegrar os validadores: jsbin.com/uqoku/2/edit
Matchu
1
@Matchu eu estava tendo o mesmo problema com .hasClass()mas sua solução parece ter feito o truque, graças
Nasir
11
Isto não funcionou para mim, mas $('element').is('.class1.class2')fez
iamchriswick
6
@iamchriswick: Isso é um pouco diferente do que o OP estava pedindo. .class1.class2corresponderão a elementos que possuem ambas as classes, mas eles estavam procurando elementos que correspondam a ambas as classes.
Matchu 18/03/16
291
element.is('.class1, .class2')

funciona, mas é 35% mais lento que

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

insira a descrição da imagem aqui

Se você duvida do que eu digo, você pode verificar em jsperf.com .

Espero que isso ajude alguém.

Simon Arnold
fonte
16
19% mais lento, grande coisa. Programadores são mais caros.
Nowaker
21
@DamianNowak se esses programadores não estiverem dispostos a escrever o que equivale a uma quantidade trivial de mais código, provavelmente não são muito caros.
Akkuma
2
... hum, mas acabei de executar isso no jsperf para Chrome 21.0.1180 e o método is () agora é cerca de 20% mais rápido. Mas o hasClass () parece mais legível.
Danyal Aytekin
3
@ psychobrm: Se você precisa verificar 10 aulas de uma só vez, o que você realmente precisa é simplificar os nomes das suas aulas. Não há razão para tal bobagem. :)
cHao
5
Pessoalmente, não vejo a necessidade de otimizar o desempenho. 12000 operações por segundo parecem rápidas o suficiente para mim. Eu diria que use o que parecer melhor para você. Otimize o desempenho quando necessário.
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']);

Isso deve ser feito, simples e fácil.

Kalel Wade
fonte
2
Está faltando um var no for (i nos seletores), criando assim um global.
Gremwell
4
Um pouco de pouca importância, mas os seletores de parâmetros devem realmente ser nomeados classes ou classNames , já que é isso que você está passando, não seletores. Os seletores teriam um ponto na frente deles, como em $ ('# elemento'). HasClasses (['. Class1', '.class2', '.class3']);
Jbyrd
10

filter () é outra opção

Reduza o conjunto de elementos correspondentes para aqueles que correspondem ao seletor ou passam no teste da função.

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

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

Que tal agora?

if (element.hasClass("class1 class2")
Robert Łoziński
fonte
3
Isso não funciona se você estiver olhando para uma condição OR.
Jason Conville
4

aqui está uma resposta que segue a sintaxe 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);

não é o mais rápido, mas é inequívoco e a solução que eu prefiro. bench: http://jsperf.com/hasclasstest/10

Henrik Myntti
fonte
Error: $self is not defined
bagofmilk
1
@bagofmilk Minha resposta foi editada por outras pessoas desde que a escrevi, há 6 anos. Desde que eu não usei jQuery em anos, eu não sei exatamente o que se pretendia com a edição, mas originalmente eu tive var $self = $(this);pouco antes de o loop for
Henrik Myntti
1

Que tal isso,

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

Fácil de usar,

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

E parece ser mais rápido, http://jsperf.com/hasclasstest/7

Okan Kocyigit
fonte
1

A respeito:

if($('.class.class2.class3').length > 0){
    //...
}
u01jmg3
fonte
3
Você não precisa do > 0. Se o comprimento for diferente de zero, ele retornará verdadeiro.
Isaac Lubow
1

jQuery

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

JS de baunilha

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

use a função js match () padrão:

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

Para usar variáveis ​​no regexp, use o seguinte:

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

a propósito, esta é a maneira mais rápida: http://jsperf.com/hasclass-vs-is-stackoverflow/22

Romualds Cirsis
fonte
Como esta resposta melhor, embora eu suspeito que looping através das classes e usando uma corda indexOf teste pode ser ainda mais rápido ainda ...
terraling
0

Funciona para mim:

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

 //do something here

 }
Rangel R. Morais
fonte
0

Você pode fazer assim:

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

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

Isso funcionou para mim:

$('.class1[class~="class2"]').append('something');
Tina
fonte
3
Esta resposta não tem nada a ver com a pergunta.
Jezen Thomas
Esta é realmente uma ótima resposta. A sintaxe do seletor acima captura todos os elementos da classe1 e da classe2. Então você pode fazer o que quiser com ele, neste caso, anexar. Não verificamos o desempenho em comparação com outros métodos, mas a sintaxe é agradável e sucinta.
Tim Wright
2
@ TimWright Esta é uma resposta terrível. A maneira normal de selecionar um elemento com 2 classes é $('.class1.class2')sem a necessidade de usar um seletor de atributos para a segunda classe. Além disso, a pergunta é perguntar como selecionar um elemento por uma das classes, não todas.
Todos os trabalhadores têm Essencial