web-dev-qa-db-fra.com

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

Utilisation de JavaScript simple (pas de jQuery), existe-t-il un moyen de vérifier si un élément contient une classe?

Actuellement, je fais ceci:

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 code HTML en ceci ...

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

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

463
daGUY

Utilisez element.classList _.contains_ méthode:

_element.classList.contains(class);
_

Cela fonctionne sur tous les navigateurs actuels et il existe des polyfill pour supporter aussi les anciens navigateurs.


Alternativement , si vous travaillez avec des navigateurs plus anciens et ne voulez pas utiliser de fonctions de remplissage multiple pour les corriger, utilisez indexOf est correct, mais vous devez le 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.

DÉMO

jQuery utilise une méthode similaire (sinon identique).


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

796
Felix Kling

La solution simple et efficace consiste à essayer la méthode . Contient.

test.classList.contains(testClass);
84
developer

Dans les navigateurs modernes, vous pouvez simplement utiliser la méthode contains de Element.classList :

_testElement.classList.contains(className)
_

Démo

_var testElement = document.getElementById('test');

console.log({
    'main' : testElement.classList.contains('main'),
    'cont' : testElement.classList.contains('cont'),
    'content' : testElement.classList.contains('content'),
    'main-cont' : testElement.classList.contains('main-cont'),
    'main-content' : testElement.classList.contains('main-content')
});_
_<div id="test" class="main main-content content"></div>_

Navigateurs supportés

enter image description here

(de CanIUse.com )


Polyfill

Si vous souhaitez utiliser Element.classList mais que vous souhaitez également prendre en charge des navigateurs plus anciens, envisagez d'utiliser ce polyfill par Eli Gray =.

40
John Slegers

Puisqu'il veut utiliser switch (), je suis surpris que personne ne l'ait encore présenté:

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/>";
    }
}
9
Thought

Voici un petit extrait Si vous essayez de vérifier si l’élément contient une classe, sans utiliser jQuery.

function hasClass(element, className) {
    return element.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className);
}

Cela explique le fait que l'élément peut contenir plusieurs noms de classe séparés par un espace.

OU


Vous pouvez également affecter cette fonction au prototype d'élément.

Element.prototype.hasClass = function(className) {
    return this.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(this.className);
};

Et le déclenche comme ceci (très similaire à la fonction .hasClass() de jQuery):

document.getElementById('MyDiv').hasClass('active');
6
Keval Bhatt

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

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 pris en charge par IE (ofcourse). Il y a beaucoup de patchs de singe sur le net pour cela.

5
KooiInc

Je connais beaucoup de réponses, mais la plupart d'entre elles concernent des fonctions et des classes supplémentaires. C’est celui que j’utilise personnellement; beaucoup plus propre et beaucoup moins de lignes de code!

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}
4
TheBlackBenzKid

Element.matches ()

element.matches (selectorString)

Selon MDN Web Docs :

La méthode Element.matches() renvoie true si l'élément serait sélectionné par la chaîne de sélecteur spécifiée; sinon, retourne false.

Par conséquent, vous pouvez utiliser Element.matches() pour déterminer si un élément contient une classe.

const element = document.querySelector('#example');

console.log(element.matches('.foo')); // true
<div id="example" class="foo bar"></div>

Voir la compatibilité du navigateur

3
Grant Miller

className n'est qu'une chaîne, vous pouvez donc utiliser la fonction habituelle indexOf pour voir si la liste de classes contient une autre chaîne.

3
David

Voici une solution triviale et insensible à la casse:

function hasClass(element, classNameToTestFor) {
    var classNames = element.className.split(' ');
    for (var i = 0; i < classNames.length; i++) {
        if (classNames[i].toLowerCase() == classNameToTestFor.toLowerCase()) {
            return true;
        }
    }
    return false;
}
2

J'ai créé une méthode prototype qui utilise classList, si possible, sinon recourt à indexOf:

Element.prototype.hasClass = Element.prototype.hasClass || 
  function(classArr){
    var hasClass = 0,
        className = this.getAttribute('class');
  
    if( this == null || !classArr || !className ) return false;
  
    if( !(classArr instanceof Array) )
      classArr = classArr.split(' ');

    for( var i in classArr )
      // this.classList.contains(classArr[i]) // for modern browsers
      if( className.split(classArr[i]).length > 1 )  
          hasClass++;

    return hasClass == classArr.length;
};


///////////////////////////////
// TESTS (see browser's console when inspecting the output)

var Elm1 = document.querySelector('p');
var Elm2 = document.querySelector('b');
var Elm3 = Elm1.firstChild; // textNode
var Elm4 = document.querySelector('text'); // SVG text

console.log( Elm1, ' has class "a": ', Elm1.hasClass('a') );
console.log( Elm1, ' has class "b": ', Elm1.hasClass('b') );
console.log( Elm1, ' has class "c": ', Elm1.hasClass('c') );
console.log( Elm1, ' has class "d": ', Elm1.hasClass('d') );
console.log( Elm1, ' has class "a c": ', Elm1.hasClass('a c') );
console.log( Elm1, ' has class "a d": ', Elm1.hasClass('a d') );
console.log( Elm1, ' has class "": ', Elm1.hasClass('') );

console.log( Elm2, ' has class "a": ', Elm2.hasClass('a') );

// console.log( Elm3, ' has class "a": ', Elm3.hasClass('a') );

console.log( Elm4, ' has class "a": ', Elm4.hasClass('a') );
<p class='a b c'>This is a <b>test</b> string</p>
<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="50px">
    <text x="10" y="20" class='a'>SVG Text Example</text>
</svg>

page de test

2
vsync

Consultez ce lien Codepen pour vérifier rapidement et facilement un élément s’il possède une classe spécifique utilisant JavaScript JavaScript ~!

hasClass (Vanilla JS)

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

C'est un peu inactif, mais si vous avez un événement qui déclenche un basculement, vous pouvez vous passer des classes:

<div id="classOne1"></div>
<div id="classOne2"></div>
<div id="classTwo3"></div>

Tu peux faire

$('body').click( function() {

    switch ( this.id.replace(/[0-9]/g, '') ) {
        case 'classOne': this.innerHTML = "I have classOne"; break;
        case 'classTwo': this.innerHTML = "I have classTwo"; break;
        default: this.innerHTML = "";
    }

});

.replace(/[0-9]/g, '') supprime les chiffres de id.

Il est un peu hacky, mais fonctionne pour les commutateurs longs sans fonctions ni boucles supplémentaires

1
Arthur Tarasov

Je pense que cette solution sera parfaite

if ($(this).hasClass("your_Class")) 
    alert("positive");            
else              
    alert("Negative");
1
Abhishek

Si l'élément n'a qu'un nom de classe, vous pouvez le vérifier rapidement en obtenant l'attribut de classe. Les autres réponses sont beaucoup plus robustes mais cela a certainement des cas d'utilisation.

if ( element.getAttribute('class') === 'classname' ) {

}
1
Brandon Brule
  1. L'astuce de Felix consistant à ajouter des espaces pour encadrer le nom de classe et la chaîne que vous recherchez constituent la bonne approche pour déterminer si les éléments ont la classe ou non.

  2. Pour avoir un comportement différent en fonction de la classe, vous pouvez utiliser des références de fonction, ou des fonctions, dans une carte:

    function fn1(element){ /* code for element with class1 */ }
    
    function fn2(element){ /* code for element with class2 */ }
    
    function fn2(element){ /* code for element with class3 */ }
    
    var fns={'class1': fn1, 'class2': fn2, 'class3': fn3};
    
    for(var i in fns) {
        if(hasClass(test, i)) {
            fns[i](test);
        }
    }
    
    • for (var i in fns) itère à travers les clés de la carte fns.
    • N'ayant pas de pause après fnsi, le code peut être exécuté chaque fois qu'il y a correspondance - ainsi, si l'élément a, par exemple, f.i., class1 et class2, les commandes fn1 et fn2 seront exécutées.
    • L'avantage de cette approche est que le code à exécuter pour chaque classe est arbitraire, comme celui de l'instruction switch. dans votre exemple, tous les cas ont effectué une opération similaire, mais demain, vous devrez peut-être faire des choses différentes pour chacun.
    • Vous pouvez simuler le cas par défaut en ayant une variable d'état indiquant si une correspondance a été trouvée dans la boucle ou non.
1
entonio

Je voudrais Poly remplir la fonctionnalité classList et utiliser la nouvelle syntaxe. De cette manière, les nouveaux navigateurs utiliseront la nouvelle implémentation (ce qui est beaucoup plus rapide) et seuls les anciens navigateurs tireront les performances du code.

https://github.com/remy/polyfills/blob/master/classList.js

1
Eric Young

Essaye celui-là:

document.getElementsByClassName = function(cl) {
   var retnode = [];
   var myclass = new RegExp('\\b'+cl+'\\b');
   var elem = this.getElementsByTagName('*');
   for (var i = 0; i < elem.length; i++) {
       var classes = elem[i].className;
       if (myclass.test(classes)) retnode.Push(elem[i]);
   }
    return retnode;
};
0
jimy

dans quel élément est actuellement la classe '.bar'? Voici une autre solution mais à vous de choisir.

var reg = /Image/g, // regexp for an image element
query = document.querySelector('.bar'); // returns [object HTMLImageElement]
query += this.toString(); // turns object into a string

if (query.match(reg)) { // checks if it matches
  alert('the class .bar is attached to the following Element:\n' + query);
}

démo jsfiddle

Bien sûr, il ne s'agit que d'une recherche d'un élément simple <img> (/Image/g) mais vous pouvez tout mettre dans un tableau comme <li> est /LI/g, <ul> = /UL/g etc.

0
Thielicious

Ceci est supporté sur IE8 +.

Premièrement, nous vérifions si classList existe si nous pouvons utiliser la méthode contains qui est prise en charge par IE10 +. Si nous sommes sur IE9 ou 8, cela revient à utiliser une expression régulière, ce qui n'est pas aussi efficace mais un polyfill concis.

if (el.classList)
  el.classList.contains(className);
else
  new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
0
Buts

Juste pour ajouter à la réponse pour les personnes essayant de trouver des noms de classe dans des éléments SVG en ligne.

Changez la fonction hasCLass() pour:

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

Au lieu d'utiliser la propriété className, vous devez utiliser la méthode getAttribute() pour récupérer le nom de la classe.

0
Ben Rudolph