Was ist die Funktion "hasClass" mit einfachem JavaScript?

313

Wie macht man jQuery's hasClassmit einfachem altem JavaScript? Beispielsweise,

<body class="foo thatClass bar">

Wie kann man mit JavaScript fragen, ob dies der Fall <body>ist thatClass?

Kyle
quelle
Ich nehme an, Sie müssten die classEigenschaft analysieren (bei mehreren Klassen werden mehrere Klassennamen in zufälliger Reihenfolge durch ein Leerzeichen getrennt) und prüfen, ob Ihr Klassenname darin enthalten ist. Nicht furchtbar schwierig, aber immer noch furchtbar unpraktisch, wenn nicht zu Lernzwecken :)
Pekka
7
Ich weiß nicht, ob ich zu spät zur Party komme, aber eine gute Seite, die Alternativen zu jQuery-Funktionen bietet,
bis zum

Antworten:

116

Sie können überprüfen, ob element.classNameÜbereinstimmungen vorliegen /\bthatClass\b/.
\bentspricht einem Wortumbruch.

Oder Sie können die eigene Implementierung von jQuery verwenden:

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

Um Ihre allgemeinere Frage zu beantworten, können Sie sich den Quellcode von jQuery auf github oder die Quelle hasClassspeziell in diesem Quell-Viewer ansehen .

SLaks
quelle
6
+1 für die jQuery-Implementierung (von für das Nachschlagen (ist das richtig Englisch?) Was ist rclasseigentlich;))
Felix Kling
6
Würde nicht \bmit "thatClass-anotherClass" übereinstimmen?
Matthew Crumley
3
Nur der Vollständigkeit halber: rclass in neueren Versionen ist "/ [\ n \ t \ r] / g" (\ r hinzugefügt)
Felix Schwarz
4
@FelixSchwarz ist richtig, in der aktuellen jQuery wurde der reguläre Ausdruck auf aktualisiert /[\t\r\n\f]/g. Es ist auch gut zu erwähnen, dass /\bclass\b/Klassennamen mit -Minuszeichen fehlschlagen können (ansonsten funktioniert es gut). Deshalb ist die Implementierung von jQuery besser und zuverlässiger. Beispiel: /\bbig\b/.test('big-text')Gibt true anstelle von erwartet false zurück.
Stano
996

Verwenden Sie einfach classList.contains():

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

Andere Verwendungen von 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');

Browser-Unterstützung:

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

classList Browser-Unterstützung

Damien
quelle
5
Dies wird in IE8 nicht unterstützt . IE8 kann .classListals Zeichenfolge abgerufen werden, erkennt jedoch die moderneren Methoden wie.classList.contains()
iono
7
@iono In der Implementierungsbeschreibung von Element.classList aus dem MDN gibt es einen Shim, der die Unterstützung für dieses Verhalten auf IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
James
3
Ich stimme @AlexanderWigmore zu, dies war unglaublich hilfreich und einfach.
Jacques Olivier
Wählt dies aus. Dies ist eine viel sauberere Art, Klassen abzufragen
user2190488
@SLaks dies sollte aktualisiert werden, um die akzeptierte Antwort bereits zu sein.
Umur Karagöz
35

Der effektivste Einzeiler, der

  • gibt einen Booleschen Wert zurück (im Gegensatz zu Orblings Antwort)
  • Gibt kein falsches Positiv zurück, wenn nach thisClasseinem Element gesucht wird , das hat class="thisClass-suffix".
  • ist mit jedem Browser bis mindestens IE6 kompatibel

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

Das Attribut, in dem die verwendeten Klassen gespeichert werden, lautet className.

Sie können also sagen:

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

Wenn Sie einen Ort suchen, der Ihnen zeigt, wie jQuery alles macht, würde ich vorschlagen:

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

Orbling
quelle
1
Ausgezeichnet. Das matchAttribut ist wieder praktisch! Macht jQuery wirklich etwas mehr als in JavaScript möglich?! Wenn nicht, ist jQuery nur ein unnötiges Gewicht von Kurzschriften.
Animaacija
1
Dies stimmt auch überein myclass-something, ebenso wie der \bBindestrich.
Marc Durdin
1
@animaacija Alle Javascript-Bibliotheken / Plugins sind im Grunde Javascript-Abkürzungen, da sie mit Javascript erstellt wurden. Die Sache ist: Abkürzungen sind immer notwendig. Das Rad niemals neu erfinden.
Edwin Stoteler
Dies ist eine großartige Lösung!
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
quelle
4
@greg_diesel: Antworten nicht entmutigen! Neue Lösungen für häufig auftretende Probleme sind mehr als willkommen.
Raveren
2
@ Raveren Während neue Lösungen für alte Probleme begrüßt werden, bringt diese spezielle Antwort nichts Neues. Es fügt dieser Frage nur Rauschen hinzu.
Emile Bergeron
1
@raveren Dies ist keine neue Lösung, es ist die gleiche wie diese Antwort, aber mit weniger Informationen.
Fund Monica Klage
13

hasClass-Funktion:

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

addClass-Funktion:

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

removeClass-Funktion:

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
quelle
11

Ich verwende eine einfache / minimale Lösung, eine Zeile, einen Cross-Browser und arbeite auch mit älteren Browsern:

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

Diese Methode ist großartig, da keine Polyfills erforderlich sind und wenn Sie sie verwenden, ist sie classListin Bezug auf die Leistung viel besser. Zumindest für mich.

Update: Ich habe eine winzige Polyfüllung erstellt, die eine Allround-Lösung ist, die ich jetzt verwende:

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

Informationen zur anderen Klassenmanipulation finden Sie in der vollständigen Datei hier .

thednp
quelle
2
Wird diese Reise über eine Klasse von notmyClassHere?
Teepeemm
2
Sie können auch fragen, ob Ihre Klasse nicht da ist. !/myClass/.test(document.body.className)Beachten Sie auch das !Symbol.
thednp
1
Ich spreche nicht davon, die Frage zu negieren. Ich denke, dass Ihre Funktion fälschlicherweise true zurückgibt, wenn der Klassenname lautet thisIsmyClassHere.
Teepeemm
1
Ich habe nur vermutet, dass Sie danach fragen, nicht genau verstanden haben, was Sie brauchen, aber haben Sie es versucht und es ist nicht richtig / falsch zurückgegeben worden, wie es sollte?
thednp
2
Dies ist nicht perfekt, da es nicht Teilzeichenfolgensicher ist. Wenn beispielsweise document.body.className = 'myClass123' ist, gibt /myClass/.test(document.body.className) true zurück ...
Zbigniew Wiadro
9

Eine gute Lösung hierfür ist die Arbeit mit classList und enthält.

Ich habe es so gemacht:

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

Sie benötigen also Ihr Element und überprüfen die Liste der Klassen. Wenn eine der Klassen mit der von Ihnen gesuchten identisch ist, wird true zurückgegeben, wenn nicht, wird false zurückgegeben!

Bastian Fießinger
quelle
6

Verwenden Sie etwas wie:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');
Alejandro Nanez
quelle
3
Ist das nicht gleichbedeutend mit myHTMLSelector.classList.indexOf('the-class')? Willst du nicht auch >=0am Ende?
Teepeemm
5
Was bringt es, [].indexOfwenn classListes eine containsMethode gibt?
Oriol
@Teepeemm nein. myHTMLSelector.classList.indexOf('the-class')Gibt den Fehler zurück, dass myHTMLSelector.classList.indexOf is not a functionda myHTMLSelector.classListkein Array ist. Aber ich denke, wenn man es mit Array.prototypeeiner Konvertierung aufruft, passiert es. Dies unterstützt möglicherweise ältere Browser, containshat jedoch eine sehr gute Unterstützung.
Ehsan88
4
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}
Alexandr Karbivnichiy
quelle
2

Diese 'hasClass'-Funktion funktioniert in IE8 +, FireFox und 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
quelle
1

Nun, alle oben genannten Antworten sind ziemlich gut, aber hier ist eine kleine einfache Funktion, die ich entwickelt habe. Es funktioniert ziemlich gut.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}
j0hnstew
quelle
3
Was bringt es, zu iterieren, wenn classListes eine containsMethode gibt?
Oriol
1

Was denkst du über diesen Ansatz?

<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
quelle
2
Ich denke, Sie mischen Ihre Variablennamen (aktiv === myClass?). Aber wird dieser Ansatz nicht falsch positiv sein class="nothatClassIsnt"?
Teepeemm
0

Hier ist der einfachste Weg:

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
quelle