Tester si un élément contient une classe?

en utilisant le JavaScript simple (pas jQuery), y a-t-il un moyen que je puisse tester pour voir si un élément contient une classe?

actuellement, je fais ceci:

HTML:

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

JS:

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

il en résulte cette sortie, qui est correcte:

I have class1

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

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

...il n'y a plus de correspondance exacte, donc j'obtiens la sortie par défaut de nothing ( "" ). Mais je veux quand même que la sortie soit I have class1 parce que le <div> still contient la classe .class1 .

330
demandé sur Thielicious 2011-05-05 17:40:19

22 réponses

Utilisation element.classList .contains méthode:

element.classList.contains(class);

cela fonctionne sur tous les navigateurs actuels et il ya des polyfills pour prendre en charge les navigateurs plus anciens aussi.


alternativement , si vous travaillez avec des navigateurs plus anciens et ne voulez pas utiliser des polyfills pour les corriger, en utilisant indexOf est correct, mais vous devez le modifier un peu:

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

sinon vous obtiendrez aussi true si la classe que vous recherchez fait partie d'un autre nom de classe.

DÉMO

jQuery utilise une méthode similaire (sinon la même).


appliqué à l'exemple:

comme cela ne fonctionne pas avec la déclaration switch, vous pourrait 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;)

581
répondu Felix Kling 2018-05-28 08:04:15

la solution facile et efficace est d'essayer .contient la méthode .

test.classList.contains(testClass);
75
répondu developer 2015-08-30 05:43:36

dans les navigateurs modernes, vous pouvez juste 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 pris en charge

enter image description here

(de CanIUse.com )


Polyfill

si vous voulez utiliser Element.classList mais vous voulez également prendre en charge les navigateurs plus anciens, envisager d'utiliser ce polyfill par Eli Grey .

31
répondu John Slegers 2017-07-12 14:49:40

Puisqu'il veut utiliser switch(), je suis surpris que personne ne l'ait encore mis de l'avant:

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/>";
    }
}
8
répondu Thought 2012-05-17 21:33:38

simplifié oneliner: 1

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

1 indexOf for arrays n'est pas supporté par IE (ofcourse). Il y a beaucoup de patches de singe à trouver sur le net pour cela.

5
répondu KooiInc 2011-05-05 16:08:35

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

// 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
répondu Dementic 2012-06-28 12:12:09

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

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

cela tient compte du fait que l'élément peut contenir plusieurs noms de classe séparés par un espace.

ou


vous pouvez aussi attribuer cette fonction à element prototype.

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

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

document.getElementById('MyDiv').hasClass('active');
4
répondu Keval Bhatt 2018-03-31 00:27:40

className est juste une chaîne de caractères pour que vous puissiez utiliser la fonction régulière indexOf pour voir si la liste des classes contient une autre chaîne de caractères.

3
répondu David 2011-05-05 13:43:33

Voici une solution triviale non sensible à 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
répondu Anders Fjeldstad 2011-05-05 13:57:07

je sais qu'il y a beaucoup de réponses, mais la plupart sont pour des fonctions supplémentaires 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');
}
2
répondu TheBlackBenzKid 2015-12-21 07:58:48

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
répondu vsync 2016-03-29 21:02:23
  1. L'astuce de Felix d'ajouter des espaces pour flanquer le nom de classe et la chaîne de caractères que vous recherchez est la bonne approche pour déterminer si les éléments ont la classe ou non.

  2. pour avoir un comportement différent selon 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 dans fns) parcourt les clés au sein du pnr de la carte.
    • N'ayant pas de pause après fnsi permet au code d'être exécuté chaque fois qu'il y a correspondance - de sorte que si l'élément a, F. I. les catégories 1 et 2, fn1 et fn2, seront exécutées.
    • L'avantage de cette approche est que le code à exécuter pour chaque classe est arbitraire, comme dans l'instruction switch; dans votre exemple tous les cas effectué une opération similaire, mais demain, vous pouvez avoir besoin de 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
répondu entonio 2011-05-05 17:54:28

je pense que la solution parfaite à ce

if ($(this).hasClass("your_Class")) 
    alert("positive");            
else              
    alert("Negative");
1
répondu Abhishek 2014-01-06 10:57:24

Je voudrais Poly remplir la fonctionnalité classList et utiliser la nouvelle syntaxe. De cette façon, les nouveaux navigateurs utiliseront la nouvelle implémentation (qui est beaucoup plus rapide) et seuls les vieux navigateurs prendront la performance du code.

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

1
répondu Eric Young 2014-01-15 19:05:49

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 ses cas d'utilisation.

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

}
1
répondu Brandon Brule 2015-01-17 20:40:59

essayez celui-ci:

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
répondu jimy 2011-05-05 13:48:15

dans lequel élément est actuellement la classe".bar' ? Voici une autre solution mais c'est à vous.

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

jsfiddle démo

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

0
répondu Thielicious 2016-07-05 21:22:56

C'est un peu éteint, mais si vous avez un événement qui déclenche le commutateur, vous pouvez faire sans classes:

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

Vous pouvez le 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 .

c'est un peu hacky, mais fonctionne pour les commutateurs longs sans fonctions ou boucles supplémentaires

0
répondu Arthur Tarasov 2017-07-19 09:58:21

voir ce lien Codepen pour un moyen rapide et facile de vérifier un élément s'il a une classe spécifique en utilisant JavaScript~!

hasClass (Vanilla js)

function hasClass(element, cls) {
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
0
répondu Jefsama 2018-03-31 00:17:14

ceci est supporté sur IE8+.

tout d'abord, nous vérifions si classList existe s'il existe, nous pouvons utiliser la méthode contains qui est supportée par IE10+. Si nous sommes sur IE9 ou 8, Il revient à utiliser un regex, qui n'est pas aussi efficace, mais est un polyfill concis.

if (el.classList)
  el.classList.contains(className);
else
  new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
0
répondu Buts 2018-07-24 00:49:36

juste pour ajouter à la réponse pour les personnes qui essaient de trouver des noms de classe dans les éléments SVG inline.

remplacer la fonction hasCLass() par:

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

au lieu d'utiliser la propriété className , vous devrez utiliser la méthode getAttribute() pour saisir le nom de la classe.

0
répondu Ben Rudolph 2018-07-25 19:14:47

pour moi, le moyen le plus élégant et le plus rapide pour y parvenir est:

function hasClass(el,cl){
   return !!el.className && !!el.className.match(new RegExp('\b('+cl+')\b'));
}
-1
répondu Pinonirvana 2018-05-30 12:22:03