Mit jQuery die Klassenliste für das Element abrufen

656

Gibt es in jQuery eine Möglichkeit, alle Klassen, die einem Element zugewiesen sind, zu durchlaufen oder einem Array zuzuweisen?

Ex.

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

Ich werde nach einer "speziellen" Klasse wie in "dolor_spec" oben suchen. Ich weiß, dass ich hasClass () verwenden könnte, aber der tatsächliche Klassenname muss zu diesem Zeitpunkt nicht unbedingt bekannt sein.

Buggabill
quelle
Wenn Sie den Klassennamen zu diesem Zeitpunkt nicht kennen und nicht HasClass () verwenden können, wie möchten Sie dann wissen, um welchen Namen es sich im Array handelt?
Doomspork
Ich entwerfe ein Formular, in dem ich eine vorläufige Validierung mit jQuery durchführe. Ich hänge die ID des Eingabeelements an die Klassenliste des Fehlerdivs an, falls eines generiert wird. Ich mache es dann möglich, auf den Fehler div zu klicken, um das fehlerhafte Eingabeelement zu fokussieren. Dieses Skript wird für mehr als ein Formular verwendet. Ich möchte daher die IDs im Skript nicht fest codieren.
Buggabill
1
Richtig, ich verstehe, warum Sie nicht hart codieren möchten. Wenn Sie sich jedoch einen Moment Zeit nehmen, um das Beispiel von redsquare zu betrachten, werden Sie feststellen, dass Sie 'someClass' in den if-Block fest codieren müssen. In beiden Fällen können Sie dies mit einer Variablen erreichen.
Doomspork
Anstatt das Klassenattribut zu verwenden, könnten Sie eine Fehlerlistenvariable in Ihrem Namespace haben, die DOM-Verweise auf die fehlerhaften Elemente enthält. Auf diese Weise müssen Sie die Attributliste nicht jedes Mal abrufen, iterieren, das DOM-Element suchen und fokussieren.
Doomspork

Antworten:

731

Sie können verwenden document.getElementById('divId').className.split(/\s+/);, um eine Reihe von Klassennamen zu erhalten.

Dann können Sie iterieren und die gewünschte finden.

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

jQuery hilft Ihnen hier nicht wirklich ...

var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
    if (item === 'someClass') {
        //do something
    }
});
rotes Quadrat
quelle
4
Genau das hätte ich getan, aber ich war mir nicht sicher, ob es eine eingebaute jQuery-Funktion gab, die Ihnen eine Sammlung der Klassen gab.
Sander
36
Zu
Ihrer Information
70
Fügen Sie selbst ein jQuery-Plugin hinzu:$.fn.classList = function() {return this[0].className.split(/\s+/);};
ripper234
1
oder dann könnten Sie: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }
Sambomartin
Kein Javascript-Experte hier. Können Sie mir sagen, ob Split (/ \ s + /) besser ist als nur Split ("")? Bei FF23 / Chrome28 / IE8 funktioniert es genauso.
Roberto Linares
288

Warum hat niemand einfach aufgelistet.

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

BEARBEITEN: Wie @MarkAmery hervorhebt, können Sie dies nicht nur, .split(' ')weil Klassennamen durch beliebige Leerzeichen getrennt werden können.

Dreamr OKelly
quelle
6
Das ist Teil der akzeptierten Antwort ... Ich brauchte alle Klassen, die auf ein Element angewendet wurden.
Buggabill
54
Weil es falsch ist! Klassen können durch jede Art von Leerzeichen getrennt werden (z. B. können Sie ein langes Klassenattribut in Ihrem HTML-Code in mehrere Zeilen einschließen), aber diese Antwort berücksichtigt dies nicht. Versuchen Sie, $('<div class="foo bar baz">').attr("class").split(' ')in Ihre Browserkonsole einzufügen (dort befindet sich ein Tabulatorzeichen). Sie erhalten ["foo", "bar baz"]anstelle der richtigen Klassenliste von ["foo", "bar", "baz"].
Mark Amery
2
@ MarkAmery ist richtig. Wenn Sie eine hätten class="foo <lots of spaces here> bar", würden Sie ein Array mit leeren Zeichenfolgenelementen erhalten.
Jacob van Lingen
4
Ich denke, in 99% der Fälle ist diese Lösung effektiv, dh vorausgesetzt, Sie steuern den HTML-Code. Ich kann mir keinen Grund vorstellen, warum wir die Möglichkeit von Tabulatoren oder mehreren Leerzeichen zwischen Klassennamen unterstützen müssten, selbst wenn HTML-Standards dies zulassen.
Gordon Rouse
5
@GordonRouse Ein zusätzliches Leerzeichen, das sich in eine Liste von Klassen einschleicht, ist ziemlich häufig, insbesondere wenn eine Art Logik die Liste der Klassen ausschreibt.
Eric
142

Bei der Unterstützung von Browsern können Sie die classListEigenschaft von DOM-Elementen verwenden .

$(element)[0].classList

Es ist ein Array-ähnliches Objekt, das alle Klassen des Elements auflistet.

Wenn Sie alte Browserversionen unterstützen müssen, die die classListEigenschaft nicht unterstützen , enthält die verknüpfte MDN-Seite auch einen Shim dafür - obwohl selbst der Shim in Internet Explorer-Versionen unter IE 8 nicht funktioniert.

Pehmolelu
quelle
Saubere Antwort und erfindet das Rad nicht neu.
Marco Sulla
@Marco Sulla: Dies hat in der Tat ein anderes Manko als die Unterstützung veralteter Software. .classListist kein echtes Array, und solche Methoden .indexOf(⋯)funktionieren nicht daran. Es ist nur ein "Array-ähnliches Objekt", während .className.split(/\s+/).indexOf(⋯)(aus der akzeptierten Antwort) funktioniert.
Incnis Mrsi
Sie können jedes iterable einfach in ein Arrayusing [...iterable]oderArray.from(iterable)
Marco Sulla
142

Hier ist ein jQuery-Plugin, das ein Array aller Klassen zurückgibt, über die die übereinstimmenden Elemente verfügen

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

Verwenden Sie es wie

$('div').classes();

In Ihrem Fall kehrt zurück

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

Sie können auch eine Funktion an die Methode übergeben, die für jede Klasse aufgerufen werden soll

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

Hier ist eine jsFiddle, die ich eingerichtet habe, um http://jsfiddle.net/GD8Qn/8/ zu demonstrieren und zu testen.

Minimiertes Javascript

;!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);
Wille
quelle
Perfekt für FullCalendar beim Kopieren von Klassen in das className- Attribut eines Ereignisses.
Dan Power
78

Sie sollten dieses versuchen:

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

Es gibt ein Array aller aktuellen Klassen des Elements zurück.

P. Petkov
quelle
Dies ist viel ordentlicher als die akzeptierte Antwort. Gibt es einen Grund, diese Methode nicht anzuwenden?
RozzA
5
Nun, ich weiß es nicht. Dies ist jedoch der richtige Weg, um Eigenschaften vom DOM-Element abzurufen. Und "classList" ist eine solche Eigenschaft, die Ihnen ein Array von CSS-Klassen gibt, die auf das Element angewendet werden.
P. Petkov
@RozzA Vielleicht war es damals nicht verfügbar? Aber ich würde sagen, dass dies ab sofort die am besten geeignete Methode ist, es sei denn, Sie verwenden nicht jQuery, wo eine einfache .classListLösung ist - Sie müssen nur auf Inkonsistenzen und / oder fehlende Browserunterstützung
achten
@ Dennis98 guter Anruf, ich vergesse manchmal, wie schnell neue Funktionen in letzter Zeit herausgekommen sind. Ich habe auch einfach js gemacht, .classListes funktioniert ziemlich gut in modernen Browsern
RozzA
1
Beachten Sie, dass die classListEigenschaft in IE 10/11 für SVG-Elemente nicht funktioniert (obwohl sie für HTML-Elemente funktioniert). Siehe 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

});
Carlisle
quelle
7

Aktualisieren:

Wie @Ryan Leonard richtig betont hat, behebt meine Antwort nicht wirklich den Punkt, den ich selbst gemacht habe ... Sie müssen doppelte Leerzeichen mit (zum Beispiel) string.replace (/ + / g, "") sowohl trimmen als auch entfernen. .. Oder Sie können den el.className teilen und dann leere Werte mit (zum Beispiel) arr.filter (Boolean) entfernen.

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

oder moderner

const classes = element.classList;

Alt:

Bei all den gegebenen Antworten sollten Sie niemals vergessen, .trim () (oder $ .trim ()) zu verwenden.

Da Klassen hinzugefügt und entfernt werden, kann es vorkommen, dass zwischen den Klassenzeichenfolgen mehrere Leerzeichen stehen. Beispiel: 'class1 class2 class3'.

Dies würde sich in ['Klasse1', 'Klasse2', '', '', '', 'Klasse3'] verwandeln.

Wenn Sie Trimmen verwenden, werden alle mehreren Leerzeichen entfernt.

DutchKevv
quelle
2
Dies ist falsch (und keine Antwort). Sowohl String.trim () als auch $ .trim () entfernen alle führenden und nachfolgenden Leerzeichen und lassen den Rest des Strings in Ruhe. jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()
Ryan Leonard
Haben Sie sich die Antworten überhaupt angesehen? Alle nativen JS-Lösungen haben nicht nach führenden und nachfolgenden Leerzeichen gesucht, sodass eine fehlerhafte Klassenliste angezeigt wurde, da das Array leere Klassen enthalten würde. JQuery macht das gleiche intern mit trim, wenn es die Klassen liest
DutchKevv
2
Ich habe die anderen Antworten gesehen und bin damit einverstanden, dass Leerzeichen zwischen Klassennamen entfernt werden sollten. Ich habe darauf hingewiesen, dass a) dies ein Kommentar zu den anderen Lösungen sein sollte, da dies keine vollständige Antwort ist. B) .trim () entfernt nicht mehrere Leerzeichen, um das zu erreichen, was Sie benötigen.
Ryan Leonard
1
Sie sind in der Tat völlig korrekt ... Entschuldigen Sie meinen zu kurzen Kommentar. Die Leerzeichen zwischen ... s.trim () werden nicht entfernt. Ersetzen (/ + / g, "") oder es wird etwas benötigt Um alle mehrfachen Leerzeichen zwischen den Klassen zu entfernen. Daneben wird el.classList fast weitgehend unterstützt, was vermutlich alles
behebt
1
überhaupt kein Problem. Glücklicherweise positiv bewertet, .classListist ein viel sauberer Ansatz!
Ryan Leonard
7
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})
alexche8
quelle
2
Dies ist ein schrecklicher Missbrauch von .map; Verwenden .eachSie diese Option .map, wenn Sie den Rückgabewert nicht benötigen . Das Aufteilen von Leerzeichen anstelle von Leerzeichen ist ebenfalls fehlerhaft - siehe meinen Kommentar zu stackoverflow.com/a/10159062/1709587 . Selbst wenn keiner dieser Punkte wahr wäre, fügt dies der Seite nichts Neues hinzu. -1!
Mark Amery
3

Könnte Ihnen das auch helfen. Ich habe diese Funktion verwendet, um Klassen von Kinderelementen zu erhalten.

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

In Ihrem Fall möchten Sie doler_ipsum Klasse u können dies jetzt tun calsses[2];.

Phönix
quelle
2

Vielen Dank dafür - ich hatte ein ähnliches Problem, da ich versuche, Objekte programmatisch mit hierarchischen Klassennamen zu verknüpfen, obwohl diese Namen meinem Skript möglicherweise nicht unbedingt bekannt sind.

In meinem Skript möchte ich, dass ein <a>Tag den <a>Hilfetext [some_class]ein- toggleund ausschaltet, indem das Tag plus die Klasse von und dann der Hilfetext die Klasse von angegeben wird [some_class]_toggle. Dieser Code findet die zugehörigen Elemente erfolgreich mit 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");}
    }
    });
} 
Alan L.
quelle
Danke Alan, ich mache etwas Ähnliches. Ich bin überrascht, dass es keinen einfacheren Weg gibt, dies zu tun.
Eric Kigathi
- 1 - tl; dr, geht auf eine Tangente los, die für die Frage nicht direkt relevant ist.
Mark Amery
2

Versuche dies. Dadurch erhalten Sie die Namen aller Klassen aus allen Elementen des Dokuments.

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

});

Hier ist das Arbeitsbeispiel: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/

Sumit Raju
quelle
1

Ich hatte ein ähnliches Problem für ein Element vom Typ Bild. Ich musste überprüfen, ob das Element einer bestimmten Klasse angehörte. Zuerst habe ich versucht mit:

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

aber ich habe ein schönes "diese Funktion ist für dieses Element nicht verfügbar".

Dann habe ich mein Element im DOM-Explorer überprüft und ein sehr schönes Attribut gesehen, das ich verwenden konnte: className. Es enthielt die Namen aller Klassen meines Elements, die durch Leerzeichen getrennt waren.

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

Sobald Sie dies erhalten haben, teilen Sie einfach die Zeichenfolge wie gewohnt.

In meinem Fall hat das funktioniert:

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

Ich gehe davon aus, dass dies mit anderen Arten von Elementen funktionieren würde (außer img).

Ich hoffe es hilft.

eva
quelle
0

Javascript bietet ein classList-Attribut für ein Knotenelement in dom. Einfach benutzen

  element.classList

gibt ein Objekt der Form zurück

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

Das Objekt verfügt über Funktionen wie enthält, hinzufügen, entfernen, die Sie verwenden können

Anuj J.
quelle
Minderwertiges Duplikat von stackoverflow.com/a/5457148/1709587, das 3 Jahre vor Ihnen veröffentlicht wurde; -1.
Mark Amery
-3

Ein bisschen spät, aber mit der Funktion verlängern () können Sie "hasClass ()" für jedes Element aufrufen, z.
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);
gesellix
quelle
10
Das war nicht die Frage.
Tomas
5
In jQuery ist diese Funktion seit Version 1.2 integriert.
Andrew
-3

Die Frage ist, wozu Jquery entwickelt wurde.

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

Und warum hat niemand .find () als Antwort gegeben?

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

Es gibt auch classList für Nicht-IE-Browser:

if element.classList.contains("dolor_spec") {  //do stuff
John Ktejik
quelle
3
- 1; Unter anderem haben Ihre ersten beiden Code-Snippets nichts mit der gestellten Frage zu tun, und Ihr letztes Snippet ist ein Syntaxfehler.
Mark Amery
-4

Hier ist die Antwort von Readsquare , um ein Array aller Klassen zurückzugeben:

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;
}

Übergeben Sie ein jQuery-Element an die Funktion, sodass ein Beispielaufruf lautet:

var myClasses = classList($('#myElement'));
Gregra
quelle
3
Warum durch das classList-Array iterieren, alle Elemente zum Klassenarray hinzufügen und das Klassenarray zurückgeben? Nur die Klassenliste zurückzugeben, sollte den gleichen Trick machen, oder?
Martijn
Nee. Da wir uns auf eine Situation beziehen, in der es viele Klassen für dasselbe Element gibt. Wenn es so einfach war, waren wir nicht hier in diesem Thread :)
Gregra
8
In diesem Thread geht es darum, eine Liste von Klassen zurückzugeben $(elem).attr('class').split(/\s+/). Vielleicht irre ich mich, aber ich sehe keinen Grund, eine Sammlung zu durchlaufen, den Inhalt in eine neue Sammlung zu kopieren und diese neue Sammlung zurückzugeben.
Martijn
-4

Ich weiß, dass dies eine alte Frage ist, aber immer noch.

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

var className=".dolor_spec" //dynamic

Wenn Sie das Element bearbeiten möchten

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

Wenn Sie überprüfen möchten, ob das Element eine Klasse hat

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

wenn mehrere Klassen

//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
dulebov.artem
quelle
1
Keines dieser Snippets befasst sich mit der gestellten Frage. -1.
Mark Amery