Obtenir la liste des classes pour l'élément avec jQuery

657

Existe-t-il un moyen dans jQuery de parcourir ou d'assigner à un tableau toutes les classes affectées à un élément?

ex.

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

Je vais chercher une classe "spéciale" comme dans "dolor_spec" ci-dessus. Je sais que je pourrais utiliser hasClass () mais le nom de classe réel n'est pas nécessairement connu à l'époque.

Buggabill
la source
Si vous ne connaissez pas le nom de la classe à ce moment, vous empêchant d'utiliser hasClass (), comment avez-vous l'intention de savoir lequel dans le tableau il s'agit?
doomspork
Je conçois un formulaire où je fais une validation préliminaire avec jQuery. J'ajoute l'id de l'élément d'entrée à la liste des classes du div d'erreur si celui-ci est généré. Je permets alors de cliquer sur le div d'erreur pour focaliser l'élément d'entrée errant. Ce script va être utilisé pour plusieurs formulaires. Je ne veux donc pas coder en dur les identifiants dans le script.
Buggabill
1
Bon, je comprends pourquoi vous ne voudriez pas coder en dur. Mais si vous prenez un moment pour regarder l'exemple de redsquare, vous verrez que vous devez coder en dur 'someClass' dans le bloc if. Dans tous les cas, vous pouvez y parvenir avec une variable.
doomspork
Plutôt que d'utiliser l'attribut class, vous pourriez avoir une variable de liste d'erreurs dans votre espace de noms qui contenait des références DOM aux éléments avec des erreurs. Ainsi, il n'est plus nécessaire d'extraire la liste d'attributs à chaque fois, de l'itérer, de trouver l'élément DOM et de le focaliser.
doomspork

Réponses:

732

Vous pouvez utiliser document.getElementById('divId').className.split(/\s+/);pour obtenir un tableau de noms de classe.

Ensuite, vous pouvez parcourir et trouver celui que vous voulez.

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

jQuery ne vous aide pas vraiment ici ...

var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
    if (item === 'someClass') {
        //do something
    }
});
carré rouge
la source
4
c'est exactement ce que j'ai fait, mais je ne savais pas s'il y avait une fonction build dans jQuery qui vous a donné une collection des classes.
Sander
36
Pour info: jQuery utilise className.split (/ \ s + /)
kͩeͣmͮpͥ
70
Ajoutez un plugin jQuery vous-même:$.fn.classList = function() {return this[0].className.split(/\s+/);};
ripper234
1
ou alors vous pourriez: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }
sambomartin
Pas un expert javascript ici. Pouvez-vous me dire si le fractionnement (/ \ s + /) est meilleur que simplement le fractionnement ("")? Cela fonctionne de la même manière pour moi dans FF23 / Chrome28 / IE8.
Roberto Linares
288

Pourquoi personne n'a simplement énuméré.

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

EDIT: Comme le souligne @MarkAmery, vous ne pouvez pas simplement .split(' ')parce que les noms de classe peuvent être séparés par n'importe quel type d'espace.

Dreamr OKelly
la source
6
Cela fait partie de la réponse acceptée ... J'avais besoin de toutes les classes qui étaient appliquées à un élément.
Buggabill
54
Parce que c'est faux! Les classes peuvent être séparées par n'importe quel type d'espace (par exemple, vous pouvez envelopper un long attribut de classe dans votre code HTML sur plusieurs lignes), mais cette réponse ne tient pas compte de cela. Essayez de coller $('<div class="foo bar baz">').attr("class").split(' ')dans la console de votre navigateur (il y a un caractère de tabulation dedans); vous obtiendrez ["foo", "bar baz"]au lieu de la liste de classe correcte de ["foo", "bar", "baz"].
Mark Amery
2
@MarkAmery a raison. Si vous en aviez un class="foo <lots of spaces here> bar", vous vous retrouveriez avec un tableau avec des éléments de chaîne vides.
Jacob van Lingen
4
Je pense que dans 99% des cas, cette solution est efficace, c'est-à-dire à condition de contrôler le HTML. Je ne peux penser à aucune raison pour laquelle nous aurions besoin de prendre en charge la possibilité de tabulations ou de multiples espaces entre les noms de classe, même si les normes HTML le permettent.
Gordon Rouse
5
@GordonRouse un espace supplémentaire se glissant dans une liste de classes est assez courant, surtout si une sorte de logique écrit la liste des classes.
Eric
142

Sur les navigateurs compatibles, vous pouvez utiliser la classListpropriété des éléments DOM .

$(element)[0].classList

Il s'agit d'un objet de type tableau répertoriant toutes les classes de l'élément.

Si vous devez prendre en charge les anciennes versions de navigateur qui ne prennent pas en charge la classListpropriété, la page MDN liée comprend également un shim pour celui-ci - bien que même le shim ne fonctionne pas sur les versions d'Internet Explorer inférieures à IE 8.

Pehmolelu
la source
Réponse nette et ne réinvente pas la roue.
Marco Sulla
@Marco Sulla: cela a en effet un défaut autre que le support sur les logiciels obsolètes. .classListn'est pas un vrai tableau, et des méthodes .indexOf(⋯)qui ne fonctionnent pas dessus. Ce n'est qu'un «objet de type tableau», alors que .className.split(/\s+/).indexOf(⋯)(d'après la réponse acceptée) fonctionne.
Incnis Mrsi
Vous pouvez facilement convertir tout itérables à un en Arrayutilisant [...iterable]ouArray.from(iterable)
Marco Sulla
142

Voici un plugin jQuery qui renverra un tableau de toutes les classes des éléments correspondants

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

Utilisez-le comme

$('div').classes();

Dans votre cas retourne

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

Vous pouvez également passer une fonction à la méthode à appeler sur chaque classe

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

Voici un jsFiddle que j'ai mis en place pour démontrer et tester http://jsfiddle.net/GD8Qn/8/

Javascript réduit

;!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);
Volonté
la source
Ajustement parfait pour FullCalendar lors de la copie de classes dans l' attribut className d'un événement.
Dan Power
78

Vous devriez essayer celui-ci:

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

Il retourne un tableau de toutes les classes actuelles de l'élément.

P.Petkov
la source
c'est beaucoup plus net que la réponse acceptée, y a-t-il une raison de ne pas utiliser cette méthode?
RozzA
5
Et bien je ne sais pas. Mais c'est la bonne façon d'obtenir des propriétés de l'élément DOM. Et "classList" est une telle propriété qui vous donne un tableau de classes CSS appliquées à l'élément.
P.Petkov
@RozzA Peut-être qu'il n'était pas disponible à l'époque? Mais je dirais que c'est la méthode la plus appropriée à l'heure actuelle, à moins que vous n'utilisiez pas jQuery, où .classListla solution est simple - il vous suffit de faire attention aux incohérences et / ou au manque de prise en charge du navigateur.
Dennis98
@ Dennis98 bon appel, j'oublie parfois la rapidité avec laquelle de nouvelles fonctionnalités sont sorties récemment. J'ai également fait du js simple, .classListcela fonctionne assez bien dans les navigateurs modernes
RozzA
1
Notez que la classListpropriété ne fonctionne pas sur IE 10/11 pour les éléments SVG (bien qu'elle fonctionne pour les éléments HTML). Voir 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
la source
7

Mise à jour:

Comme @Ryan Leonard l'a souligné correctement, ma réponse ne résout pas vraiment le point que j'ai fait moi-même ... Vous devez à la fois couper et supprimer les espaces doubles avec (par exemple) string.replace (/ + / g, "") .. Ou vous pouvez diviser el.className puis supprimer les valeurs vides avec (par exemple) arr.filter (Boolean).

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

ou plus moderne

const classes = element.classList;

Vieux:

Avec toutes les réponses données, vous ne devez jamais oublier d'utiliser .trim () (ou $ .trim ())

Parce que les classes sont ajoutées et supprimées, il peut arriver qu'il y ait plusieurs espaces entre la chaîne de classe .. par exemple 'class1 class2 class3' ..

Cela deviendrait ['class1', 'class2', '', '', '', 'class3'] ..

Lorsque vous utilisez le découpage, tous les espaces multiples sont supprimés.

DutchKevv
la source
2
C'est incorrect (et pas une réponse). String.trim () et $ .trim () suppriment tous les espaces de début et de fin et laissent le reste de la chaîne tranquille. jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()
Ryan Leonard
Avez-vous même regardé les réponses? Toutes les solutions natives JS n'a pas vérifié de diriger et de fuite des espaces blancs, donnant ainsi une liste de classe défectueuse, car il y aurait des classes vides dans le tableau .. jQuery fait la même chose en interne avec garniture quand il lit les classes
DutchKevv
2
J'ai vu les autres réponses et je suis d'accord que les espaces doivent être supprimés entre les noms de classe. Je faisais remarquer que a) cela devrait être un commentaire sur les autres solutions, car ce n'est pas une réponse complète b) .trim () ne supprime pas plusieurs espaces pour obtenir ce dont vous avez besoin.
Ryan Leonard
1
Vous avez tout à fait raison en effet ... Désolé pour mon commentaire rapide .. Il ne supprime pas les espaces entre les deux ... sur trim (). Replace (/ + / g, "") ou quelque chose serait nécessaire pour supprimer tous les espaces multiples entre les classes .. À côté de cela, el.classList est presque largement pris en charge, corrigeant tout je suppose ..
DutchKevv
1
aucun problème du tout. Heureusement, .classListc'est une approche beaucoup plus propre!
Ryan Leonard
7
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})
alexche8
la source
2
C'est un horrible abus de .map; utilisez .eachsi vous n'avez pas besoin de .mapla valeur de retour de. Le fractionnement sur les espaces plutôt que sur les espaces blancs est également cassé - voir mon commentaire sur stackoverflow.com/a/10159062/1709587 . Même si aucun de ces points n'était vrai, cela n'ajoute rien de nouveau à la page. -1!
Mark Amery
3

Cela pourrait-il aussi vous aider? J'ai utilisé cette fonction pour obtenir des classes d'éléments 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();
    });
}

Dans votre cas, vous voulez que la classe doler_ipsum u puisse faire comme ça maintenant calsses[2];.

Phénix
la source
2

Merci pour cela - J'avais un problème similaire, car j'essaie de relier par programme les objets aux noms de classe hiérarchiques, même si ces noms ne sont pas nécessairement connus de mon script.

Dans mon script, je veux qu'une <a>balise active / désactive le texte d'aide en donnant la <a>balise [some_class]plus la classe de toggle, puis en donnant à son texte d'aide la classe de [some_class]_toggle. Ce code trouve avec succès les éléments associés à l'aide de 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.
la source
Merci Alan, je fais quelque chose de similaire, je suis surpris qu'il n'y ait pas de moyen plus simple de le faire.
Eric Kigathi
- 1 - tl; dr, part sur une tangente sans rapport direct avec la question.
Mark Amery
2

Essaye ça. Cela vous donnera les noms de toutes les classes de tous les éléments du document.

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

});

Voici l'exemple de travail: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/

Sumit Raju
la source
1

J'ai eu un problème similaire, pour un élément de type image. J'avais besoin de vérifier si l'élément était d'une certaine classe. J'ai d'abord essayé avec:

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

mais j'ai obtenu une belle "cette fonction n'est pas disponible pour cet élément".

Ensuite, j'ai inspecté mon élément sur l'explorateur DOM et j'ai vu un très bel attribut que je pouvais utiliser: className. Il contenait les noms de toutes les classes de mon élément séparés par des espaces vides.

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

Une fois que vous obtenez cela, divisez simplement la chaîne comme d'habitude.

Dans mon cas, cela a fonctionné:

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

Je suppose que cela fonctionnerait avec d'autres types d'éléments (outre img).

J'espère que cela aide.

Eva
la source
0

javascript fournit un attribut classList pour un élément de noeud dans dom. Simplement en utilisant

  element.classList

retournera un objet de forme

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

L'objet a des fonctions comme contient, ajouter, supprimer que vous pouvez utiliser

Anuj J
la source
Duplicata inférieur de stackoverflow.com/a/5457148/1709587 qui a été publié 3 ans avant vous; -1.
Mark Amery
-3

Un peu tard, mais l'utilisation de la fonction extend () vous permet d'appeler "hasClass ()" sur n'importe quel élément, par exemple:
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
la source
10
Ce n'était pas la question.
Tomas
5
De plus, jQuery a intégré cette fonction depuis la version 1.2.
Andrew
-3

La question est de savoir ce que Jquery est conçu pour faire.

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

Et pourquoi personne n'a donné .find () comme réponse?

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

Il existe également classList pour les navigateurs non IE:

if element.classList.contains("dolor_spec") {  //do stuff
john ktejik
la source
3
- 1; entre autres problèmes, vos deux premiers extraits de code ne sont pas liés à la question posée et votre extrait final est une erreur de syntaxe.
Mark Amery
-4

Voilà, juste ajusté la réponse de readsquare pour retourner un tableau de toutes les classes:

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

Passez un élément jQuery à la fonction, pour qu'un exemple d'appel soit:

var myClasses = classList($('#myElement'));
Gregra
la source
3
Pourquoi parcourir le tableau classList, ajouter tous les éléments au tableau classes et renvoyer le tableau classes? Le simple retour de classList devrait faire la même astuce, non?
Martijn
Nan. Puisque nous faisons référence à une situation où il existe de nombreuses classes pour le même élément. Si c'était si facile, nous n'étions pas ici sur ce fil :)
Gregra
8
Ce fil de discussion est sur le retour d'une liste de classes, et simplement le retour $(elem).attr('class').split(/\s+/)fait cela. Je me trompe peut-être, mais je ne vois aucune raison de parcourir une collection, de copier le contenu dans une nouvelle collection et de renvoyer cette nouvelle collection.
Martijn
-4

Je sais que c'est une vieille question mais quand même.

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

var className=".dolor_spec" //dynamic

Si vous souhaitez manipuler l'élément

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

Si vous voulez vérifier si l'élément a une classe

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

si plusieurs classes

//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
la source
1
Aucun de ces extraits ne répond à la question posée. -1.
Mark Amery du