Ottieni l'elenco delle classi per l'elemento con jQuery


657

Esiste un modo in jQuery per eseguire il ciclo o assegnare a un array tutte le classi assegnate a un elemento?

ex.

<div class="Lorem ipsum dolor_spec sit amet">Hello World!</div>

Cercherò una classe "speciale" come in "dolor_spec" sopra. So che potrei usare hasClass () ma il nome della classe effettiva potrebbe non essere necessariamente noto al momento.


Se al momento non conosci il nome della classe, impedendoti di usare hasClass (), come intendi sapere quale dell'array è?
doomspork,

Sto progettando un modulo in cui sto eseguendo una convalida preliminare con jQuery. Sto aggiungendo l'id dell'elemento di input all'elenco di classi del div dell'errore se viene generato. Sto quindi rendendo possibile fare clic sul div dell'errore per focalizzare l'elemento di input errato. Questo script verrà utilizzato per più di un modulo. Pertanto, non voglio codificare gli ID nello script.
Buggabill

1
Bene, capisco perché non vorresti codificare. Ma se prendi un momento per esaminare l'esempio di redsquare vedrai che devi codificare "someClass" nel blocco if. In entrambi i casi è possibile ottenere questo risultato con una variabile.
doomspork,

Invece di utilizzare l'attributo class, potresti avere una variabile dell'elenco errori all'interno del tuo spazio dei nomi che conteneva riferimenti DOM agli elementi con errori. Eliminando così la necessità di estrarre ogni volta l'elenco di attributi, iterarlo, trovare l'elemento DOM e focalizzarlo.
doomspork,

Risposte:


732

Puoi usare document.getElementById('divId').className.split(/\s+/); per ottenere una matrice di nomi di classe.

Quindi puoi iterare e trovare quello che desideri.

var classList = document.getElementById('divId').className.split(/\s+/);
for (var i = 0; i < classList.length; i++) {
    if (classList[i] === 'someClass') {
        //do something
    }
}

jQuery non ti aiuta davvero qui ...

var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
    if (item === 'someClass') {
        //do something
    }
});

4
è esattamente quello che avrei fatto, ma non ero sicuro che ci fosse una funzione build in jQuery che ti dava una raccolta di classi.
Sander,

36
A proposito: jQuery utilizza className.split (/ \ s + /)
kͩeͣmͮpͥ ͩ

70
Aggiungi tu stesso un plugin jQuery:$.fn.classList = function() {return this[0].className.split(/\s+/);};
ripper234

1
o poi potresti: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }
sambomartin,

Non un esperto di JavaScript qui. Puoi dirmi se split (/ \ s + /) è meglio che semplicemente fare split ("")? Funziona allo stesso modo per me in FF23 / Chrome28 / IE8.
Roberto Linares,

288

Perché nessuno ha semplicemente elencato.

$(element).attr("class").split(/\s+/);

EDIT: Come sottolinea @MarkAmery, non puoi semplicemente .split(' ')perché i nomi delle classi possono essere separati da qualsiasi tipo di spazio bianco.


6
Questo fa parte della risposta accettata ... Avevo bisogno di tutte le classi che venivano applicate a un elemento.
Buggabill,

54
Perché è sbagliato! Le classi possono essere separate da qualsiasi tipo di spazio bianco (ad es. Puoi avvolgere un attributo di classe lunga nel tuo HTML su più righe), ma questa risposta non riesce a spiegarlo. Prova a incollare $('<div class="foo bar baz">').attr("class").split(' ')nella tua console del browser (c'è un carattere tab all'interno); otterrai ["foo", "bar baz"]invece l'elenco di classi corretto di ["foo", "bar", "baz"].
Mark Amery,

2
@MarkAmery ha ragione. Se avessi un class="foo <lots of spaces here> bar", finiresti con un array con elementi stringa vuoti.
Jacob van Lingen,

4
Penso che nel 99% dei casi questa soluzione sia efficace, vale a dire se stai controllando l'HTML. Non riesco a pensare a nessun motivo per cui avremmo bisogno di supportare la possibilità di tabulazioni o spazi multipli tra i nomi delle classi anche se gli standard HTML lo consentono.
Gordon Rouse,

5
@GordonRouse è abbastanza comune uno spazio aggiuntivo che si insinua in un elenco di classi, soprattutto se un qualche tipo di logica sta scrivendo l'elenco di classi.
Eric,

142

Sui browser di supporto, puoi utilizzare la classListproprietà degli elementi DOM .

$(element)[0].classList

È un oggetto simile a un array che elenca tutte le classi dell'elemento.

Se è necessario supportare le versioni di browser precedenti che non supportano la classListproprietà, la pagina MDN collegata include anche uno shim, sebbene anche lo shim non funzionerà su versioni di Internet Explorer inferiori a IE 8.


Risposta pulita e non reinventa la ruota.
Marco Sulla

@Marco Sulla: questo ha davvero un difetto diverso dal supporto su software obsoleto. .classListnon è un array vero e metodi che .indexOf(⋯)non funzionano su di esso. È solo un "oggetto simile a matrice", mentre .className.split(/\s+/).indexOf(⋯)(dalla risposta accettata) funziona.
Incnis Mrsi,

Puoi facilmente convertire qualsiasi iterabile in un Arrayutilizzo [...iterable]oArray.from(iterable)
Marco Sulla

142

Ecco un plugin jQuery che restituirà un array di tutte le classi degli elementi corrispondenti

;!(function ($) {
    $.fn.classes = function (callback) {
        var classes = [];
        $.each(this, function (i, v) {
            var splitClassName = v.className.split(/\s+/);
            for (var j = 0; j < splitClassName.length; j++) {
                var className = splitClassName[j];
                if (-1 === classes.indexOf(className)) {
                    classes.push(className);
                }
            }
        });
        if ('function' === typeof callback) {
            for (var i in classes) {
                callback(classes[i]);
            }
        }
        return classes;
    };
})(jQuery);

Usalo come

$('div').classes();

Nel tuo caso ritorna

["Lorem", "ipsum", "dolor_spec", "sit", "amet"]

È inoltre possibile passare una funzione al metodo da chiamare su ogni classe

$('div').classes(
    function(c) {
        // do something with each class
    }
);

Ecco un jsFiddle che ho impostato per dimostrare e testare http://jsfiddle.net/GD8Qn/8/

Javascript minimizzato

;!function(e){e.fn.classes=function(t){var n=[];e.each(this,function(e,t){var r=t.className.split(/\s+/);for(var i in r){var s=r[i];if(-1===n.indexOf(s)){n.push(s)}}});if("function"===typeof t){for(var r in n){t(n[r])}}return n}}(jQuery);

Perfetta per FullCalendar quando si copiano le classi nell'attributo className di un evento.
Dan Power,

78

Dovresti provare questo:

$("selector").prop("classList")

Restituisce un array di tutte le classi correnti dell'elemento.


questo è molto più ordinato della risposta accettata, c'è qualche motivo per non usare questo metodo?
RozzA

5
Beh non lo so. Ma questo è il modo corretto di ottenere proprietà dall'elemento DOM. E "classList" è una tale proprietà che ti dà una matrice di classi css applicate all'elemento.
P.Petkov,

@RozzA Forse all'epoca non era disponibile? Ma direi che questo è il metodo più appropriato al momento, a meno che tu non usi jQuery, dove una .classListsoluzione è semplice : devi solo prestare attenzione alle incoerenze e / o al supporto mancante del browser ..
Dennis98

@ Dennis98 bella chiamata, a volte dimentico quanto recentemente sono venute fuori nuove funzionalità. Ho anche fatto js semplice .classListche funziona abbastanza bene nei browser moderni
RozzA

1
Si noti che la classListproprietà non funziona su IE 10/11 per gli elementi SVG (sebbene funzioni per gli elementi HTML). Vedi developer.mozilla.org/en-US/docs/Web/API/Element/classList
Métoule

17
var classList = $(element).attr('class').split(/\s+/);
$(classList).each(function(index){

     //do something

});

7

Aggiornare:

Come ha sottolineato correttamente @Ryan Leonard, la mia risposta non risolve davvero il punto che mi sono reso ... Devi tagliare e rimuovere i doppi spazi con (ad esempio) string.replace (/ + / g, "") .. Oppure potresti dividere el.className e quindi rimuovere i valori vuoti con (ad esempio) arr.filter (Booleano).

const classes = element.className.split(' ').filter(Boolean);

o più moderno

const classes = element.classList;

Vecchio:

Con tutte le risposte fornite, non dovresti mai dimenticare l'utente .trim () (o $ .trim ())

Poiché le classi vengono aggiunte e rimosse, può accadere che vi siano più spazi tra le stringhe di classe .. ad es. 'Class1 class2 class3' ..

Ciò si trasformerebbe in ['class1', 'class2', '', '', '', 'class3'] ..

Quando si utilizza il ritaglio, tutti gli spazi multipli vengono rimossi.


2
Questo non è corretto (e non una risposta). Sia String.trim () che $ .trim () rimuovono tutti gli spazi bianchi iniziali e finali e lasciano solo il resto della stringa. jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()
Ryan Leonard

Hai anche dato un'occhiata alle risposte? Tutte le soluzioni JS native non hanno verificato gli spazi bianchi iniziali e finali, dando così un elenco di classi difettoso, poiché ci sarebbero classi vuote nell'array .. jQuery fa lo stesso internamente con trim quando legge le classi
DutchKevv

2
Ho visto le altre risposte e sono d'accordo che gli spazi bianchi dovrebbero essere rimossi tra i nomi delle classi. Stavo sottolineando che a) questo dovrebbe essere un commento sulle altre soluzioni, in quanto non è una risposta completa b) .trim () non rimuove più spazi per ottenere ciò di cui hai bisogno.
Ryan Leonard,

1
Hai assolutamente ragione ... Scusa per il mio rapido commento .. Non rimuove gli spazi tra ... s.trim (). Replace (/ + / g, "") o qualcosa sarebbe necessario per rimuovere tutti gli spazi multipli tra le classi .. Accanto a questo, el.classList è quasi ampiamente supportato,
risolvendo

1
nessun problema. Felicemente votato, .classListè un approccio molto più pulito!
Ryan Leonard,

7
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})

2
Questo è un orribile abuso di .map; utilizzare .eachse non è necessario .mapil valore restituito. Anche la divisione degli spazi anziché di qualsiasi spazio bianco viene interrotta - vedere il mio commento su stackoverflow.com/a/10159062/1709587 . Anche se nessuno di questi punti era vero, questo non aggiunge nulla di nuovo alla pagina. -1!
Mark Amery,

3

Questo potrebbe aiutare anche te. Ho usato questa funzione per ottenere classi di elementi childern ..

function getClickClicked(){
    var clickedElement=null;
    var classes = null;<--- this is array
    ELEMENT.on("click",function(e){//<-- where element can div,p span, or any id also a class
        clickedElement = $(e.target);
        classes = clickedElement.attr("class").split(" ");
        for(var i = 0; i<classes.length;i++){
            console.log(classes[i]);
        }
        e.preventDefault();
    });
}

Nel tuo caso vuoi la classe doler_ipsum che puoi fare così adesso calsses[2];.


2

Grazie per questo - Stavo avendo un problema simile, poiché sto cercando di mettere in relazione programmaticamente gli oggetti con nomi di classe gerarchici, anche se quei nomi potrebbero non essere necessariamente noti al mio script.

Nel mio script, desidero che un <a>tag attivi / disattivi il testo guida fornendo il <a>tag [some_class]più la classe di toggle, e quindi dando il testo guida alla classe di [some_class]_toggle. Questo codice trova correttamente gli elementi correlati usando jQuery:

$("a.toggle").toggle(function(){toggleHelp($(this), false);}, function(){toggleHelp($(this), true);});

function toggleHelp(obj, mode){
    var classList = obj.attr('class').split(/\s+/);
    $.each( classList, function(index, item){
    if (item.indexOf("_toggle") > 0) {
       var targetClass = "." + item.replace("_toggle", "");
       if(mode===false){$(targetClass).removeClass("off");}
       else{$(targetClass).addClass("off");}
    }
    });
} 

Grazie Alan, sto facendo qualcosa di simile, sono sorpreso che non ci sia un modo più semplice per farlo.
Eric Kigathi,

- 1 - tl; dr, si spegne su una tangente non direttamente pertinente alla domanda.
Mark Amery,

2

Prova questo. Questo ti darà i nomi di tutte le classi da tutti gli elementi del documento.

$(document).ready(function() {
var currentHtml="";
$('*').each(function() {
    if ($(this).hasClass('') === false) {
        var class_name = $(this).attr('class');
        if (class_name.match(/\s/g)){
            var newClasses= class_name.split(' ');
            for (var i = 0; i <= newClasses.length - 1; i++) {
                if (currentHtml.indexOf(newClasses[i]) <0) {
                    currentHtml += "."+newClasses[i]+"<br>{<br><br>}<br>"
                }
            }
        }
        else
        {
            if (currentHtml.indexOf(class_name) <0) {
                currentHtml += "."+class_name+"<br>{<br><br>}<br>"
            }
        }
    }
    else
    {
        console.log("none");
    }
});
$("#Test").html(currentHtml);

});

Ecco l'esempio funzionante: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/


1

Ho avuto un problema simile, per un elemento di tipo immagine. Dovevo verificare se l'elemento apparteneva a una determinata classe. Per prima cosa ho provato con:

$('<img>').hasClass("nameOfMyClass"); 

ma ho ottenuto un bel "questa funzione non è disponibile per questo elemento".

Poi ho ispezionato il mio elemento su DOM Explorer e ho visto un attributo molto carino che potevo usare: className. Conteneva i nomi di tutte le classi del mio elemento separate da spazi vuoti.

$('img').className // it contains "class1 class2 class3"

Una volta ottenuto questo, basta dividere la stringa come al solito.

Nel mio caso questo ha funzionato:

var listOfClassesOfMyElement= $('img').className.split(" ");

Suppongo che funzionerebbe con altri tipi di elementi (oltre a img).

Spero che sia d'aiuto.


0

javascript fornisce un attributo classList per un elemento nodo in dom. Semplicemente usando

  element.classList

restituirà un oggetto di forma

  DOMTokenList {0: "class1", 1: "class2", 2: "class3", length: 3, item: function, contains: function, add: function, remove: function…}

L'oggetto ha funzioni come contiene, aggiungi, rimuovi che puoi usare


Duplicato inferiore di stackoverflow.com/a/5457148/1709587 pubblicato 3 anni prima di te; -1.
Mark Amery,

-3

Un po 'in ritardo, ma usando la funzione ext () puoi chiamare "hasClass ()" su qualsiasi elemento, ad esempio:
var hasClass = $('#divId').hasClass('someClass');

(function($) {
$.extend({
    hasClass: new function(className) {
        var classAttr = $J(this).attr('class');
        if (classAttr != null && classAttr != undefined) {
            var classList = classAttr.split(/\s+/);
            for(var ix = 0, len = classList.length;ix < len;ix++) {
                if (className === classList[ix]) {
                    return true;
                }
            }
        }
        return false;
    }
}); })(jQuery);

10
Non era questa la domanda.
Tomas,

5
Inoltre, jQuery ha questa funzione integrata dalla versione 1.2.
Andrew,

-3

La domanda è: cosa Jquery è progettato per fare.

$('.dolor_spec').each(function(){ //do stuff

E perché nessuno ha dato .find () come risposta?

$('div').find('.dolor_spec').each(function(){
  ..
});

Esiste anche classList per browser non IE:

if element.classList.contains("dolor_spec") {  //do stuff

3
- 1; tra gli altri problemi, i primi due frammenti di codice non sono correlati alla domanda posta e il frammento finale è un errore di sintassi.
Mark Amery,

-4

Ecco qua, ho appena modificato la risposta di readsquare per restituire una matrice di tutte le classi:

function classList(elem){
   var classList = elem.attr('class').split(/\s+/);
    var classes = new Array(classList.length);
    $.each( classList, function(index, item){
        classes[index] = item;
    });

    return classes;
}

Passa un elemento jQuery alla funzione, in modo che una chiamata di esempio sia:

var myClasses = classList($('#myElement'));

3
Perché iterare attraverso l'array classList, aggiungere tutti gli elementi all'array class e restituire l'array class? Restituire la classList dovrebbe fare lo stesso trucco, giusto?
Martijn,

No. Dato che ci riferiamo a una situazione in cui ci sono molte classi per lo stesso elemento. Se fosse così facile, non eravamo qui su questa discussione :)
Gregra,

8
Questo thread riguarda la restituzione di un elenco di classi e semplicemente la restituzione lo $(elem).attr('class').split(/\s+/)fa. Forse sto sbagliando, ma non vedo alcun motivo per scorrere una raccolta, copiare i contenuti in una nuova raccolta e restituire quella nuova raccolta.
Martijn,

-4

So che questa è una vecchia domanda, ma comunque.

<div id="specId" class="Lorem ipsum dolor_spec sit amet">Hello World!</div>

var className=".dolor_spec" //dynamic

Se vuoi manipolare l'elemento

$("#specId"+className).addClass('whatever');

Se vuoi verificare se l'elemento ha classe

 $("#specId"+className).length>0

se più classi

//if you want to select ONE of the classes
var classNames = ['.dolor_spec','.test','.test2']
$("#specId"+classNames).addClass('whatever');
$("#specId"+classNames).length>0
//if you want to select all of the classes
var result = {className: ""};
classNames.forEach(function(el){this.className+=el;},result);
var searchedElement= $("#specId"+result.className);
searchedElement.addClass('whatever');
searchedElement.length>0

1
Nessuno di questi frammenti risponde alla domanda posta; -1.
Mark Amery,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.