jQuery hasClass () - busca más de una clase

162

Con:

if(element.hasClass("class"))

Puedo verificar si hay una clase, pero ¿hay alguna manera fácil de verificar si "elemento" tiene alguna clase?

Estoy usando:

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

Lo cual no es tan malo, pero estoy pensando en algo como:

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

Lo que desafortunadamente no funciona.

¿Hay algo como eso?

Hans
fuente

Respuestas:

227

Qué tal si:

element.is('.class1, .class2')
Matchu
fuente
9
No, porque eso buscaría elementos que tengan ambas clases. Creo que Marcel está buscando elementos con una o más de varias clases.
Giles Van Gruisen
Justo ahora noté que tengo 4 elementos id = "hola" allí. Versión fija para hacer felices a los validadores: jsbin.com/uqoku/2/edit
Matchu
1
@Matchu Estaba teniendo el mismo problema, .hasClass()pero su solución parece haber funcionado, gracias
Nasir
11
Esto no funcionó para mí, pero lo $('element').is('.class1.class2')hizo
iamchriswick
66
@iamchriswick: Eso es ligeramente diferente de lo que estaba pidiendo OP. .class1.class2coincidirá con elementos que tengan ambas clases, pero estaban buscando elementos que coincidan con cualquiera de las clases.
Matchu
291
element.is('.class1, .class2')

funciona, pero es un 35% más lento que

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

ingrese la descripción de la imagen aquí

Si dudas de lo que digo, puedes verificarlo en jsperf.com .

Espero que esto ayude a alguien.

Simon Arnold
fuente
16
19% más lento, gran cosa. Los programadores son más caros.
Nowaker
21
@DamianNowak si esos programadores no están dispuestos a escribir lo que equivale a una cantidad trivial de más código, probablemente no sean muy caros.
Akkuma
2
... um, pero acabo de ejecutar esto en jsperf para Chrome 21.0.1180 y el método is () ahora es aproximadamente un 20% más rápido. Pero el hasClass () parece más legible.
Danyal Aytekin
3
@psychobrm: Si tiene que verificar 10 clases a la vez, lo que realmente necesita es simplificar los nombres de sus clases. No hay razón para tales tonterías. :)
cHao
55
Personalmente no puedo ver la necesidad de optimizar el rendimiento. 12000 operaciones por segundo me parecen lo suficientemente rápidas. Yo diría que use lo que le parezca más agradable. Optimice el rendimiento cuando surja la necesidad.
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']);

Esto debería hacerlo, simple y fácil.

Kalel Wade
fuente
2
Te falta una var en for (i en selectores), creando así un global.
Gremwell
44
Un punto un poco menor, pero los selectores de parámetros realmente deberían llamarse clases o classNames , ya que eso es lo que está pasando, no los selectores. Los selectores tendrían un punto delante de ellos, como en $ ('# elemento'). HasClasses (['. Class1', '.class2', '.class3']);
jbyrd
10

filter () es otra opción

Reduzca el conjunto de elementos coincidentes a los que coinciden con el selector o pasan la prueba de la función.

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

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

¿Qué tal esto?

if (element.hasClass("class1 class2")
Robert Łoziński
fuente
3
Esto no funciona si está viendo una condición OR.
Jason Conville el
4

Aquí hay una respuesta que sigue la sintaxis 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);

No es el más rápido, pero es inequívoco y la solución que prefiero. banco: http://jsperf.com/hasclasstest/10

Henrik Myntti
fuente
Error: $self is not defined
bagofmilk
1
@bagofmilk Mi respuesta ha sido editada por otros desde que la escribí hace 6 años. Como no he usado jQuery en años, no sé exactamente lo que se pretendía con la edición, pero originalmente tenía var $self = $(this);justo antes del ciclo for
Henrik Myntti
1

¿Qué hay de esto?

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

Y parece ser más rápido, http://jsperf.com/hasclasstest/7

Okan Kocyigit
fuente
1

Qué pasa:

if($('.class.class2.class3').length > 0){
    //...
}
u01jmg3
fuente
3
No necesitas el > 0. Si la longitud no es cero, devolverá verdadero.
Isaac Lubow
1

jQuery

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

Vanilla JS

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

use la función predeterminada js match ():

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

para usar variables en regexp, use esto:

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

Por cierto, esta es la forma más rápida: http://jsperf.com/hasclass-vs-is-stackoverflow/22

Romualds Cirsis
fuente
Al igual que esta respuesta mejor, aunque sospecho que bucle a través de las clases y el uso de una cadena indexOf prueba podría ser incluso más rápido todavía ...
terraling
0

Funciona para mi:

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

 //do something here

 }
Rangel R. Morais
fuente
0

Puedes hacerlo de esta manera:

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

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

Esto funcionó para mí:

$('.class1[class~="class2"]').append('something');
Tina
fuente
3
Esta respuesta no tiene nada que ver con la pregunta formulada.
Jezen Thomas el
Esta es realmente una gran respuesta. La sintaxis del selector anterior toma todos los elementos con class1 y class2. Entonces puedes hacer lo que quieras con él, en este caso, adjuntar. No he verificado el rendimiento en comparación con otros métodos, pero la sintaxis es agradable y sucinta.
Tim Wright
2
@TimWright Esta es una respuesta terrible. La forma normal de seleccionar un elemento con 2 clases es $('.class1.class2')sin necesidad de utilizar un selector de atributos para la segunda clase. Además, la pregunta es cómo seleccionar un elemento por una de las clases, no todas.
Todos los trabajadores son esenciales