Uzyskaj listę klas dla elementu za pomocą jQuery

657

Czy w jQuery istnieje sposób na zapętlenie lub przypisanie do tablicy wszystkich klas przypisanych do elementu?

dawny.

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

Będę szukał „specjalnej” klasy jak w „dolor_spec” powyżej. Wiem, że mógłbym użyć hasClass (), ale rzeczywista nazwa klasy może nie być w tym czasie znana.

Buggabill
źródło
Jeśli nie znasz nazwy klasy, co uniemożliwia użycie hasClass (), jak zamierzasz wiedzieć, która jest w tablicy?
doomspork
Projektuję formularz, w którym przeprowadzam wstępne sprawdzenie poprawności za pomocą jQuery. Dołączam identyfikator elementu wejściowego do listy klas div błędu, jeśli taki jest generowany. Umożliwiam kliknięcie div div błędu, aby skupić błędny element wejściowy. Ten skrypt będzie używany w więcej niż jednej formie. Dlatego nie chcę sztywno kodować identyfikatorów w skrypcie.
Buggabill
1
Rozumiem, dlaczego nie chcesz na stałe kodować. Ale jeśli poświęcisz chwilę na przyjrzenie się przykładowi redsquare, zobaczysz, że musisz zakodować „someClass” w bloku if. Tak czy inaczej można to osiągnąć za pomocą zmiennej.
doomspork
Zamiast używać atrybutu class, możesz mieć zmienną listy błędów w przestrzeni nazw, która zawierała odwołania DOM do elementów z błędami. Eliminując w ten sposób potrzebę ciągnięcia listy atrybutów za każdym razem, iteruj ją, znajdź element DOM i skoncentruj go.
doomspork

Odpowiedzi:

731

Możesz użyć, document.getElementById('divId').className.split(/\s+/);aby uzyskać tablicę nazw klas.

Następnie możesz iterować i znaleźć ten, który chcesz.

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

jQuery nie pomaga ci tutaj ...

var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
    if (item === 'someClass') {
        //do something
    }
});
plac Czerwony
źródło
4
właśnie to zrobiłem, ale nie byłem pewien, czy istnieje funkcja wbudowana w jQuery, która dała ci kolekcję klas.
Sander,
36
Do Twojej wiadomości: jQuery używa className.split (/ \ s + /)
kͩeͣmͮpͥ
70
Dodaj wtyczkę jQuery:$.fn.classList = function() {return this[0].className.split(/\s+/);};
ripper234
1
lub wtedy możesz: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }
sambomartin 19.10.12
Tutaj nie jestem ekspertem od javascript. Czy możesz mi powiedzieć, czy split (/ \ s + /) jest lepszy niż zwykłe dzielenie („”)? Działa tak samo dla mnie w FF23 / Chrome28 / IE8.
Roberto Linares
288

Dlaczego nikogo nie wymieniono?

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

EDYCJA: Jak wskazuje @MarkAmery, nie można po prostu .split(' ')dlatego, że nazwy klas można oddzielić dowolnym rodzajem białych znaków.

Dreamr OKelly
źródło
6
To część przyjętej odpowiedzi ... Potrzebowałem wszystkich klas, które zostały zastosowane do elementu.
Buggabill,
54
Ponieważ to źle! Klasy mogą być oddzielone dowolnym rodzajem spacji (np. Możesz owinąć atrybut HTML długiej klasy w wielu wierszach), ale ta odpowiedź nie uwzględnia tego. Spróbuj wkleić $('<div class="foo bar baz">').attr("class").split(' ')w konsoli przeglądarki (jest tam znak tabulacji); otrzymasz ["foo", "bar baz"]zamiast prawidłowej listy klas ["foo", "bar", "baz"].
Mark Amery
2
@ MarkAmery ma rację. Gdybyś miał class="foo <lots of spaces here> bar", skończyłbyś tablicą z pustymi elementami łańcucha.
Jacob van Lingen,
4
Myślę, że w 99% przypadków to rozwiązanie jest skuteczne, tzn. Pod warunkiem, że kontrolujesz HTML. Nie mogę wymyślić żadnego powodu, dla którego potrzebowalibyśmy obsługiwać tabulacje lub wiele spacji między nazwami klas, nawet jeśli pozwalają na to standardy HTML.
Gordon Rouse,
5
@GordonRouse dodatkowa przestrzeń wkradająca się na listę klas jest dość powszechna, szczególnie jeśli jakaś logika spisuje listę klas.
Eric
142

W obsługiwanych przeglądarkach można używać classListwłaściwości elementów DOM .

$(element)[0].classList

Jest to obiekt podobny do tablicy, zawierający listę wszystkich klas tego elementu.

Jeśli potrzebujesz obsługiwać starsze wersje przeglądarki, które nie obsługują tej classListwłaściwości, połączona strona MDN również zawiera podkładkę dla niej - chociaż nawet podkładka nie będzie działać w wersjach Internet Explorer poniżej IE 8.

Pehmolelu
źródło
Czysta odpowiedź i nie wymyśla koła na nowo.
Marco Sulla,
@Marco Sulla: jest to rzeczywiście wada inna niż obsługa przestarzałego oprogramowania. .classListnie jest prawdziwą tablicą i .indexOf(⋯)nie działają na niej takie metody . Jest to tylko „obiekt podobny do tablicy”, podczas gdy .className.split(/\s+/).indexOf(⋯)(z przyjętej odpowiedzi) działa.
Incnis Mrsi
Możesz łatwo przekonwertować dowolną iterowalną na Arrayużywającą [...iterable]lubArray.from(iterable)
Marco Sulla
142

Oto wtyczka jQuery, która zwróci tablicę wszystkich klas, które mają pasujące elementy

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

Użyj tego jak

$('div').classes();

W twoim przypadku powraca

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

Możesz także przekazać funkcję do metody, która zostanie wywołana w każdej klasie

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

Oto jsFiddle, który skonfigurowałem, aby zademonstrować i przetestować http://jsfiddle.net/GD8Qn/8/

Minified 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);
Będzie
źródło
Idealne dopasowanie do FullCalendar podczas kopiowania klas do atrybutu className zdarzenia.
Dan Power
78

Powinieneś spróbować tego:

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

Zwraca tablicę wszystkich bieżących klas elementu.

P. Petkov
źródło
jest to znacznie bardziej rozsądne niż zaakceptowana odpowiedź, czy jest jakiś powód, aby nie używać tej metody?
RozzA
5
Nie wiem. Ale jest to właściwy sposób na uzyskanie właściwości z elementu DOM. A „classList” to taka właściwość, która daje tablicę klas css zastosowanych do elementu.
P.Petkov
@RozzA Może to wtedy nie było dostępne? Ale powiedziałbym, że jest to obecnie najbardziej odpowiednia metoda, chyba że nie używasz jQuery, gdzie proste .classListjest rozwiązanie - wystarczy zwrócić uwagę na niespójności i / lub brak obsługi przeglądarki.
Dennis98
@ Dennis98 dobre połączenie, czasami zapominam, jak szybko pojawiły się nowe funkcje. Zrobiłem też zwykły js .classList, działa całkiem dobrze w nowoczesnych przeglądarkach
RozzA
1
Zauważ, że ta classListwłaściwość nie działa w IE 10/11 dla elementów SVG (choć działa dla elementów HTML). Zobacz 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
źródło
7

Aktualizacja:

Jak prawidłowo wskazał @Ryan Leonard, moja odpowiedź tak naprawdę nie naprawia punktu, który sam sobie stworzyłem ... Musisz zarówno przycinać, jak i usuwać podwójne spacje (na przykład) string.replace (/ + / g, "") .. Lub możesz podzielić el.className, a następnie usunąć puste wartości za pomocą (na przykład) arr.filter (Boolean).

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

lub bardziej nowoczesny

const classes = element.classList;

Stary:

Przy wszystkich podanych odpowiedziach nigdy nie powinieneś zapominać o użytkowniku .trim () (lub $ .trim ())

Ponieważ klasy są dodawane i usuwane, może się zdarzyć, że między łańcuchem klas jest wiele spacji .. np. „Class1 class2 class3” ..

Zmieniłoby się to w [„klasa 1”, „klasa 2”, „”, „”, „”, „klasa 3”] ..

Podczas korzystania z przycinania wszystkie wielokrotne spacje są usuwane.

DutchKevv
źródło
2
To jest niepoprawne (i nie odpowiedź). Zarówno String.trim (), jak i $ .trim () usuwają wszystkie początkowe i końcowe białe spacje i pozostawiają resztę ciągu w spokoju. jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()
Ryan Leonard
Czy w ogóle spojrzałeś na odpowiedzi? Wszystkie natywne rozwiązania JS nie sprawdzały początkowych i końcowych białych znaków, dając w ten sposób wadliwą listę klas, ponieważ w tablicy byłyby puste klasy. JQuery robi to samo wewnętrznie z przycinaniem podczas odczytywania klas
DutchKevv
2
Widziałem inne odpowiedzi i zgadzam się, że spacje między nazwami klas powinny być usuwane. Zwracałem uwagę, że a) powinien to być komentarz do innych rozwiązań, ponieważ nie jest to pełna odpowiedź b) .trim () nie usuwa wielu spacji, aby osiągnąć to, czego potrzebujesz.
Ryan Leonard
1
Naprawdę masz całkowitą rację ... Przepraszam za mój szybki komentarz .. Nie usuwa spacji między ... s.trim (). Replace (/ + / g, ""), albo coś by było potrzebne aby usunąć wszystkie spacje między klasami. Oprócz tego el.classList jest prawie powszechnie obsługiwany, naprawiając wszystko, co przypuszczam ..
DutchKevv,
1
żaden problem. Szczęśliwie pozytywnie oceniany, .classListjest znacznie czystszym podejściem!
Ryan Leonard
7
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})
alexche8
źródło
2
To okropne nadużycie .map; użyj, .eachjeśli nie potrzebujesz .mapwartości zwracanej. Dzielenie spacji zamiast jakichkolwiek białych znaków również jest zepsute - patrz mój komentarz na stackoverflow.com/a/10159062/1709587 . Nawet jeśli żaden z tych punktów nie był prawdziwy, nie dodaje to nic nowego do strony. -1!
Mark Amery
3

Może to też może ci pomóc. Użyłem tej funkcji, aby uzyskać klasy elementu potomnego ..

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

W twoim przypadku chcesz, aby klasa doler_ipsum mogła zrobić to teraz calsses[2];.

Feniks
źródło
2

Dzięki za to - miałem podobny problem, ponieważ próbuję programowo powiązać obiekty z hierarchicznymi nazwami klas, nawet jeśli te nazwy niekoniecznie są znane mojemu skryptowi.

W moim skrypcie chcę, aby <a>tag włączał / wyłączał tekst pomocy, podając <a>tag [some_class]plus klasę toggle, a następnie podając jej tekst pomocy klasy [some_class]_toggle. Ten kod skutecznie odnajduje powiązane elementy za pomocą 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.
źródło
Dzięki Alan, robię coś podobnego, jestem zaskoczony, że nie ma prostszego sposobu, aby to zrobić.
Eric Kigathi
- 1 - tl; dr, przechodzi na styczną niezwiązaną bezpośrednio z pytaniem.
Mark Amery
2

Spróbuj tego. Otrzymasz nazwy wszystkich klas ze wszystkich elementów dokumentu.

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

});

Oto działający przykład: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/

Sumit Raju
źródło
1

Miałem podobny problem dotyczący elementu obrazu typu. Musiałem sprawdzić, czy element należał do określonej klasy. Najpierw próbowałem z:

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

ale mam fajny „ta funkcja nie jest dostępna dla tego elementu”.

Następnie sprawdziłem mój element w eksploratorze DOM i zobaczyłem bardzo fajny atrybut, którego mogłem użyć: className. Zawierał nazwy wszystkich klas mojego elementu oddzielone spacjami.

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

Gdy to otrzymasz, po prostu podziel sznurek jak zwykle.

W moim przypadku to zadziałało:

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

Zakładam, że działałoby to z innymi rodzajami elementów (oprócz img).

Mam nadzieję, że to pomoże.

eva
źródło
0

javascript zapewnia atrybut classList dla elementu węzła w dom. Po prostu używa

  element.classList

zwróci obiekt formy

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

Obiekt ma takie funkcje, jak zawiera, dodaje, usuwa, których można użyć

Anuj J
źródło
Niższy duplikat stackoverflow.com/a/5457148/1709587, który został opublikowany 3 lata przed tobą; -1.
Mark Amery
-3

Trochę za późno, ale użycie funkcji ext () pozwala wywołać „hasClass ()” na dowolnym elemencie, np .:
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
źródło
10
To nie było pytanie.
Tomas
5
Ponadto jQuery ma tę funkcję wbudowaną od wersji 1.2.
Andrew
-3

Pytanie brzmi: do czego służy Jquery.

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

I dlaczego nikt nie podał .find () jako odpowiedzi?

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

Istnieje także lista klas dla przeglądarek innych niż IE:

if element.classList.contains("dolor_spec") {  //do stuff
John KTejik
źródło
3
- 1; wśród innych problemów pierwsze dwa fragmenty kodu nie są powiązane z zadanym pytaniem, a ostatni fragment jest błędem składniowym.
Mark Amery
-4

Proszę bardzo, poprawiłem odpowiedź readsquare , aby zwrócić tablicę wszystkich klas:

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

Przekaż element jQuery do funkcji, aby przykładowe wywołanie miało postać:

var myClasses = classList($('#myElement'));
Gregra
źródło
3
Po co iterować po tablicy classList, dodawać wszystkie elementy do tablicy klas i zwracać tablicę klas? Zwrócenie klasy classList powinno zrobić tę samą sztuczkę, prawda?
Martijn
Nie. Ponieważ mamy na myśli sytuację, w której istnieje wiele klas dla tego samego elementu. Gdyby to było takie proste, nie
byłoby
8
Wątek ten dotyczy zwracania listy klas i po prostu powrót $(elem).attr('class').split(/\s+/)robi. Może się mylę, ale nie widzę żadnego powodu, aby iterować kolekcję, kopiować zawartość do nowej kolekcji i zwracać tę nową kolekcję.
Martijn
-4

Wiem, że to stare pytanie, ale nadal.

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

var className=".dolor_spec" //dynamic

Jeśli chcesz manipulować elementem

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

Jeśli chcesz sprawdzić, czy element ma klasę

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

jeśli wiele klas

//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
źródło
1
Żaden z tych fragmentów nie odnosi się do zadanego pytania; -1.
Mark Amery