Qu'est-ce que la fonction «hasClass» avec du JavaScript pur?

313

Comment faites-vous des jQuery hasClassavec du JavaScript ordinaire? Par exemple,

<body class="foo thatClass bar">

Quelle est la façon JavaScript de demander si <body>oui thatClass?

Kyle
la source
Je suppose que vous devrez analyser la classpropriété (qui, dans le cas de plusieurs classes, aura plusieurs noms de classe dans un ordre aléatoire séparés par un espace) et vérifier si votre nom de classe s'y trouve. Pas terriblement difficile, mais toujours terriblement gênant si ce n'est à des fins d'apprentissage :)
Pekka
7
Je ne sais pas si je suis en retard pour la fête mais un bon site qui offre des alternatives aux fonctions jQuery est youmightnotneedjquery.com
jusqu'au

Réponses:

116

Vous pouvez vérifier si des element.classNamecorrespondances /\bthatClass\b/.
\bcorrespond à une coupure de mot.

Ou, vous pouvez utiliser la propre implémentation de jQuery:

var className = " " + selector + " ";
if ( (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(" thatClass ") > -1 ) 

Pour répondre à votre question plus générale, vous pouvez consulter le code source de jQuery sur github ou la source hasClassspécifiquement dans ce visualiseur de source .

SLaks
la source
6
+1 pour la mise en œuvre de jQuery (pour avoir recherché (est-ce le bon anglais?) Ce rclassqui est réellement;))
Felix Kling
6
Ne \bcorrespondrait pas à "thatClass-anotherClass"?
Matthew Crumley
3
juste pour être complet: rclass dans les versions récentes est "/ [\ n \ t \ r] / g" (\ r ajouté)
Felix Schwarz
4
@FelixSchwarz a raison, dans jQuery actuelle l'expression rationnelle a été mise à jour /[\t\r\n\f]/g. Il est également bon de mentionner que cela /\bclass\b/peut échouer pour les noms de classe avec le -signe moins (à part que cela fonctionne bien), c'est pourquoi l'implémentation de jQuery est meilleure et plus fiable. Par exemple: /\bbig\b/.test('big-text')retourne vrai au lieu de faux attendu.
Stano
996

Utilisez simplement classList.contains():

if (document.body.classList.contains('thatClass')) {
    // do some stuff
}

Autres utilisations de classList:

document.body.classList.add('thisClass');
// $('body').addClass('thisClass');

document.body.classList.remove('thatClass');
// $('body').removeClass('thatClass');

document.body.classList.toggle('anotherClass');
// $('body').toggleClass('anotherClass');

Prise en charge du navigateur:

  • Chrome 8.0
  • Firefox 3.6
  • IE 10
  • Opera 11.50
  • Safari 5.1

classList Prise en charge du navigateur

Damien
la source
5
Ceci n'est pas pris en charge dans IE8 . IE8 peut récupérer .classListsous forme de chaîne, mais il ne reconnaîtra pas les méthodes les plus modernes telles que.classList.contains()
iono
7
@iono Dans la description de l'implémentation Element.classList du MDN, il existe un shim qui étend la prise en charge de ce comportement à IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
James
3
Je suis d'accord avec @AlexanderWigmore, c'était incroyablement utile et simple.
Jacques Olivier
Vote cela. C'est une façon beaucoup plus propre d'interroger les classes
user2190488
@SLaks cela devrait être mis à jour pour être déjà la réponse acceptée.
Umur Karagöz
35

La doublure la plus efficace

  • renvoie un booléen (par opposition à la réponse d'Orbling)
  • Ne renvoie pas de faux positif lors de la recherche thisClasssur un élément qui aclass="thisClass-suffix" .
  • est compatible avec tous les navigateurs jusqu'à au moins IE6

function hasClass( target, className ) {
    return new RegExp('(\\s|^)' + className + '(\\s|$)').test(target.className);
}
raveren
la source
28

L'attribut qui stocke les classes en cours d'utilisation est className .

Vous pouvez donc dire:

if (document.body.className.match(/\bmyclass\b/)) {
    ....
}

Si vous voulez un emplacement qui vous montre comment jQuery fait tout, je suggère:

http://code.jquery.com/jquery-1.5.js

Orbling
la source
1
Excellent. L' matchattribut est à nouveau utile! Est-ce que jQuery fait vraiment plus que ce qui est possible en JavaScript?! Sinon, jQuery n'est qu'un poids inutile de raccourcis.
animaacija
1
Cela correspond également myclass-something, comme \bcorrespond au trait d'union.
Marc Durdin
1
@animaacija Toutes les bibliothèques / plugins javascript sont essentiellement des raccourcis javascript car ils sont construits avec javascript. La chose est: les raccourcis sont toujours nécessaires. Ne réinventez jamais la roue.
Edwin Stoteler
C'est une excellente solution!
Manuel Abascal
28

// 1. Use if for see that classes:

if (document.querySelector(".section-name").classList.contains("section-filter")) {
  alert("Grid section");
  // code...
}
<!--2. Add a class in the .html:-->

<div class="section-name section-filter">...</div>

StiveAZ
la source
4
@greg_diesel: ne découragez pas les réponses! De nouvelles solutions aux problèmes communs sont plus que bienvenues.
raveren
2
@Raveren alors que de nouvelles solutions à d'anciens problèmes sont les bienvenues, cette réponse particulière n'apporte rien de nouveau. Cela ne fait qu'ajouter du bruit à cette question.
Emile Bergeron
1
@raveren Ce n'est pas une nouvelle solution, c'est la même chose que cette réponse mais avec moins d'informations.
Fund Monica's Lawsuit
13

Fonction hasClass:

HTMLElement.prototype.hasClass = function(cls) {
    var i;
    var classes = this.className.split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] == cls) {
            return true;
        }
    }
    return false;
};

Fonction addClass:

HTMLElement.prototype.addClass = function(add) {
    if (!this.hasClass(add)){
        this.className = (this.className + " " + add).trim();
    }
};

Fonction removeClass:

HTMLElement.prototype.removeClass = function(remove) {
    var newClassName = "";
    var i;
    var classes = this.className.replace(/\s{2,}/g, ' ').split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] !== remove) {
            newClassName += classes[i] + " ";
        }
    }
    this.className = newClassName.trim();
};
Gawin
la source
11

J'utilise une solution simple / minimale, une ligne, un navigateur croisé et fonctionne également avec les navigateurs hérités:

/\bmyClass/.test(document.body.className) // notice the \b command for whole word 'myClass'

Cette méthode est excellente car elle ne nécessite pas de polyfills et si vous les utilisez pourclassList c'est beaucoup mieux en termes de performances. Au moins pour moi.

Mise à jour: j'ai fait un minuscule polyfill qui est une solution polyvalente que j'utilise maintenant:

function hasClass(element,testClass){
  if ('classList' in element) { return element.classList.contains(testClass);
} else { return new Regexp(testClass).exec(element.className); } // this is better

//} else { return el.className.indexOf(testClass) != -1; } // this is faster but requires indexOf() polyfill
  return false;
}

Pour l'autre manipulation de classe, voir le fichier complet ici .

thednp
la source
2
Est-ce que ce voyage sur une classe de notmyClassHere?
Teepeemm
2
Vous pouvez également demander si votre classe n'est pas là. !/myClass/.test(document.body.className)Notez également le !symbole.
thednp
1
Je ne parle pas de nier la question. Je pense que votre fonction retournera incorrectement true si le nom de la classe est thisIsmyClassHere.
Teepeemm
1
Je devinais seulement que c'est ce que vous demandez, je ne comprenais pas exactement ce dont vous avez besoin, mais l'avez-vous essayé et cela n'a pas réussi à retourner vrai / faux comme il se doit?
thednp
2
Ce n'est pas parfait car ce n'est pas une preuve de sous-chaînes. Par exemple, lorsque document.body.className = 'myClass123', puis /myClass/.test(document.body.className) retourne vrai ...
Zbigniew Wiadro
9

une bonne solution pour cela est de travailler avec classList et contains.

je l'ai fait comme ça:

... for ( var i = 0; i < container.length; i++ ) {
        if ( container[i].classList.contains('half_width') ) { ...

Vous avez donc besoin de votre élément et vérifiez la liste des classes. Si l'une des classes est la même que celle que vous recherchez, elle retournera true sinon elle retournera false!

Bastian Fießinger
la source
6

Utilisez quelque chose comme:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');
Alejandro Nanez
la source
3
N'est-ce pas équivalent à myHTMLSelector.classList.indexOf('the-class')? Tu ne veux pas aussi >=0à la fin?
Teepeemm
5
Quel est l'intérêt d'utiliser [].indexOfif classLista une containsméthode?
Oriol
@Teepeemm no. myHTMLSelector.classList.indexOf('the-class')renvoie l'erreur qui, myHTMLSelector.classList.indexOf is not a functioncar myHTMLSelector.classListn'est pas un tableau. Mais je suppose que lors de l'appel en utilisant Array.prototypeune conversion, cela se produit. Cela peut prendre en charge un navigateur plus ancien, mais containsa un très bon support.
Ehsan88
4
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}
Alexandr Karbivnichiy
la source
2

Cette fonction 'hasClass' fonctionne dans IE8 +, FireFox et Chrome:

hasClass = function(el, cls) {
    var regexp = new RegExp('(\\s|^)' + cls + '(\\s|$)'),
        target = (typeof el.className === 'undefined') ? window.event.srcElement : el;
    return target.className.match(regexp);
}
manufosela
la source
1

Eh bien, toutes les réponses ci-dessus sont plutôt bonnes, mais voici une petite fonction simple que j'ai préparée. Cela fonctionne plutôt bien.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}
j0hnstew
la source
3
Quel est l'intérêt d'itérer si classLista une containsméthode?
Oriol
1

Que pensez-vous de cette approche?

<body class="thatClass anotherClass"> </body>

var bodyClasses = document.querySelector('body').className;
var myClass = new RegExp("thatClass");
var trueOrFalse = myClass.test( bodyClasses );

https://jsfiddle.net/5sv30bhe/

Marian07
la source
2
Je pense que vous mélangez vos noms de variables (actif === maClasse?). Mais cette approche ne donnera-t-elle pas un faux positif class="nothatClassIsnt"?
Teepeemm du
0

Voici le moyen le plus simple:

var allElements = document.querySelectorAll('*');
for (var i = 0; i < allElements.length; i++) {
    if (allElements[i].hasAttribute("class")) {
         //console.log(allElements[i].className);
         if (allElements[i].className.includes("_the _class ")) { 
              console.log("I see the class");
         }
    }
}
Community Ans
la source