738 votes

Vérifier si un élément contient une classe en JavaScript ?

En utilisant un simple JavaScript (pas jQuery), existe-t-il un moyen de vérifier si un élément contient un cours ?

Actuellement, je fais ça :

var test = document.getElementById("test");
var testClass = test.className;

switch (testClass) {
  case "class1":
    test.innerHTML = "I have class1";
    break;
  case "class2":
    test.innerHTML = "I have class2";
    break;
  case "class3":
    test.innerHTML = "I have class3";
    break;
  case "class4":
    test.innerHTML = "I have class4";
    break;
  default:
    test.innerHTML = "";
}

<div id="test" class="class1"></div>

Le problème est que si je change le HTML en ceci...

<div id="test" class="class1 class5"></div>

...il n'y a plus de correspondance exacte, et j'obtiens donc le résultat par défaut de rien ( "" ). Mais je veux toujours que la sortie soit I have class1 parce que le <div> toujours contient le site .class1 classe.

7 votes

Element.classList.contains(cls)

1330voto

Felix Kling Points 247451

Utilisez element.classList .contains méthode :

element.classList.contains(class);

Cela fonctionne sur tous les navigateurs actuels et il existe des polyfills pour prendre en charge les navigateurs plus anciens également.


Ou bien Si vous travaillez avec des navigateurs plus anciens et que vous ne souhaitez pas utiliser les polyfills pour les corriger, l'utilisation de l'option indexOf est correcte, mais vous devez la modifier un peu :

function hasClass(element, className) {
    return (' ' + element.className + ' ').indexOf(' ' + className+ ' ') > -1;
}

Sinon, vous obtiendrez également true si la classe que vous recherchez fait partie d'un autre nom de classe.

DEMO

jQuery utilise une méthode similaire (si ce n'est la même).


Appliqué à l'exemple :

Comme cela ne fonctionne pas avec l'instruction switch, vous pouvez obtenir le même effet avec ce code :

var test = document.getElementById("test"),
    classes = ['class1', 'class2', 'class3', 'class4'];

test.innerHTML = "";

for(var i = 0, j = classes.length; i < j; i++) {
    if(hasClass(test, classes[i])) {
        test.innerHTML = "I have " + classes[i];
        break;
    }
}

C'est aussi moins redondant ;)

0 votes

Génial, mais comment puis-je utiliser cela en combinaison avec l'instruction switch pour pouvoir changer la sortie en fonction des classes que la div contient ?

0 votes

@daGUY : Que voulez-vous faire avec l'instruction switch de toute façon ? Par exemple, le deuxième div a deux classes mais il ne produirait que I have class1 comme vous utilisez break . Si vous voulez afficher toutes les classes d'un élément, vous pouvez simplement utiliser la fonction className et le diviser sur les espaces blancs. Ou quel est votre objectif réel ?

0 votes

@Felix Kling : J'ai besoin que le innerHTML du div change entre quatre chaînes différentes en fonction de la classe qu'il contient. J'ai juste utilisé "J'ai la classe 1", etc. comme exemples - les vraies chaînes de caractères sont toutes différentes. Je n'afficherai qu'une seule chaîne à la fois, sans en combiner aucune (d'où les pauses après chaque cas). Je veux simplement que cela fonctionne même si la classe correspondante est l'une des multiples classes de la division.

10voto

Thought Points 300

Comme il veut utiliser switch(), je suis surpris que personne ne l'ait encore proposé :

var test = document.getElementById("test");
var testClasses = test.className.split(" ");
test.innerHTML = "";
for(var i=0; i<testClasses.length; i++) {
    switch(testClasses[i]) {
        case "class1": test.innerHTML += "I have class1<br/>"; break;
        case "class2": test.innerHTML += "I have class2<br/>"; break;
        case "class3": test.innerHTML += "I have class3<br/>"; break;
        case "class4": test.innerHTML += "I have class4<br/>"; break;
        default: test.innerHTML += "(unknown class:" + testClasses[i] + ")<br/>";
    }
}

1 votes

Je me demandais justement la même chose, mais oui, c'est ce qui se rapproche le plus du problème original !

6voto

Dementic Points 3288

C'est un peu vieux, mais peut-être que quelqu'un trouvera ma solution utile :

// Fix IE's indexOf Array
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement) {
        if (this == null) throw new TypeError();
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) return -1;
        var n = 0;
        if (arguments.length > 0) {
            n = Number(arguments[1]);
            if (n != n) n = 0;
            else if (n != 0 && n != Infinity && n != -Infinity) n = (n > 0 || -1) * Math.floor(Math.abs(n));
        }
        if (n >= len) return -1;
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) if (k in t && t[k] === searchElement) return k;
        return -1;
    }
}
// add hasClass support
if (!Element.prototype.hasClass) {
    Element.prototype.hasClass = function (classname) {
        if (this == null) throw new TypeError();
        return this.className.split(' ').indexOf(classname) === -1 ? false : true;
    }
}

0 votes

Utiliser : 'élément.hasClass('classname') ;

0 votes

Pourquoi avez-vous utilisé t.length >>> 0 ? Pour autant que je sache, c'est un noop si vous utilisez '0', non ?

0 votes

Wow tant de code pour quelque chose de simple. Pourquoi ne pas utiliser une expression régulière et ne pas réinventer la roue ? Vous pourriez simplement utiliser /^class_name_you_are_searching_for$/.test(myElement.className)

5voto

David Points 20209

className n'est qu'une chaîne de caractères, ce qui permet d'utiliser la commande régulière indexOf pour voir si la liste des classes contient une autre chaîne.

1 votes

Qu'en est-il des tests pour la classe class dans l'exemple ci-dessus ?

7 votes

Par expérience, cette méthode peut être assez risquée : elle retournera vrai lorsque vous chercherez la classe foo sur un élément qui a le foobar classe.

2 votes

Bien sûr, il faut juste être conscient de ce que l'on teste. Le code de Felix fonctionne bien en utilisant des espaces comme délimiteur.

5voto

KooiInc Points 38845

Un oneliner simplifié : 1

function hasClassName(classname,id) {
 return  String ( ( document.getElementById(id)||{} ) .className )
         .split(/\s/)
         .indexOf(classname) >= 0;
}

1 indexOf pour les tableaux n'est pas prise en charge par IE (bien sûr). Il existe de nombreux correctifs de singe à trouver sur le net pour cela.

1 votes

Le problème avec les limites des mots est que certains caractères valides pour les noms de classe tels que - sont considérés comme des limites de mots. Par exemple, chercher foo et la classe est foo-bar donne true .

0 votes

Vous avez raison. J'ai enlevé l'original, ajouté une autre approche. C'est toujours un oneliner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X