Überprüfen Sie, ob ein Element eine Klasse in JavaScript enthält.

588

Gibt es eine Möglichkeit, mit einfachem JavaScript (nicht jQuery) zu überprüfen, ob ein Element eine Klasse enthält ?

Derzeit mache ich das:

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>

Das Problem ist, dass, wenn ich den HTML-Code in diesen ...

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

... gibt es keine genaue Übereinstimmung mehr, daher erhalte ich die Standardausgabe von nothing ( ""). Aber ich möchte immer noch, dass die Ausgabe ist, I have class1weil die <div>noch die Klasse enthält.class1 .

daGUY
quelle
5
element.classList.contains (cls)
Ronnie Royston

Antworten:

1038

Verwenden element.classList .contains Methode:

element.classList.contains(class);

Dies funktioniert in allen aktuellen Browsern und es gibt Polyfills, die auch ältere Browser unterstützen.


Alternativ , wenn Sie mit älteren Browsern arbeiten und keine Polyfills verwenden möchten, um diese zu beheben, verwenden SieindexOf ist richtig, aber man muss es ein wenig zwicken:

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

Andernfalls erhalten Sie auch, truewenn die gesuchte Klasse Teil eines anderen Klassennamens ist.

DEMO

jQuery verwendet eine ähnliche (wenn nicht dieselbe) Methode.


Auf das Beispiel angewendet:

Da dies nicht mit der switch-Anweisung zusammenarbeitet, können Sie mit diesem Code den gleichen Effekt erzielen:

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

Es ist auch weniger redundant;)

Felix Kling
quelle
Genial, aber wie verwende ich das in Kombination mit der switch-Anweisung, damit ich die Ausgabe basierend auf den Klassen ändern kann, die das div enthält?
daGUY
@daGUY: Was willst du überhaupt mit der switch-Anweisung machen? ZB Die zweite divhat zwei Klassen, wird aber nur so ausgegeben, I have class1wie Sie sie verwenden break. Wenn Sie jede Klasse eines Elements ausgeben möchten, können Sie die einfach nehmen classNameund auf Leerzeichen aufteilen. Oder was ist dein eigentliches Ziel?
Felix Kling
@ Felix Kling: Ich brauche das innerHTML des Div, um zwischen vier verschiedenen Strings zu wechseln, je nachdem welche Klasse es enthält. Ich habe nur "Ich habe Klasse 1" usw. als Beispiele verwendet - die realen Zeichenfolgen sind alle unterschiedlich. Ich werde jeweils nur eine Zeichenfolge anzeigen und keine kombinieren (daher die Unterbrechungen nach jedem Fall). Ich möchte nur, dass es auch dann noch funktioniert, wenn die passende Klasse eine von mehreren Klassen im div ist.
daGUY
@ Felix Kling: das hat es geschafft, vielen Dank! Ich gebe eigentlich nicht die Namen der Klassen aus, sondern eine von vier völlig unterschiedlichen Zeichenfolgen, deshalb habe ich sie mit ein paar IF / ELSE IF-Anweisungen leicht modifiziert, um jede zu behandeln. Funktioniert aber perfekt.
daGUY
1
Gibt es einen bestimmten Grund, warum Sie vorher und nachher Leerzeichen hinzugefügt haben?
Ced
93

Die einfache und effektive Lösung ist die Methode .contains .

test.classList.contains(testClass);
Entwickler
quelle
3
die containsMethode einer element.classListEigenschaft
user907860
7
NB! Nicht in allen Browsern unterstützt, weitere Informationen hier: caniuse.com/#feat=classlist
Silver
4
Dies ist eine großartige Antwort und ich glaube, dass .contains () jetzt eine viel breitere Unterstützung hat.
Nicholas Kreidberg
49

In modernen Browsern können Sie einfach die folgende containsMethode verwenden Element.classList:

testElement.classList.contains(className)

Demo

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>


Unterstützte Browser

Geben Sie hier die Bildbeschreibung ein

(von CanIUse.com )


Polyfill

Wenn Sie Element.classListältere Browser verwenden möchten, aber auch ältere Browser unterstützen möchten, sollten Sie diese Polyfüllung von Eli Gray verwenden .

John Slegers
quelle
10

Da er switch () verwenden möchte, bin ich überrascht, dass dies noch niemand veröffentlicht hat:

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/>";
    }
}
Habe gedacht
quelle
1
Ich habe mich nur das Gleiche gefragt, aber ja, das kommt dem ursprünglichen Problem am nächsten!
Silver Ringvee
8

Element.matches ()

element.matches (selectorString)

Laut MDN Web Docs :

Die Element.matches()Methode gibt zurück, trueob das Element durch die angegebene Auswahlzeichenfolge ausgewählt wird. Andernfalls wird zurückgegeben false.

Daher können Sie verwenden, Element.matches()um festzustellen, ob ein Element eine Klasse enthält.

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

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

Browserkompatibilität anzeigen

Grant Miller
quelle
7

Hier ist ein kleiner Ausschnitt Wenn Sie überprüfen möchten, ob das Element eine Klasse enthält, ohne jQuery zu verwenden.

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

Dies erklärt die Tatsache, dass das Element möglicherweise mehrere durch Leerzeichen getrennte Klassennamen enthält.

ODER


Sie können diese Funktion auch dem Elementprototyp zuweisen.

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

Und lösen Sie es so aus (sehr ähnlich der .hasClass()Funktion von jQuery ):

document.getElementById('MyDiv').hasClass('active');
Keval Bhatt
quelle
Ich bevorzuge diese Lösung mehr. Es vermeidet das Problem, dass der Klassenname teilweise mit einer anderen Klasse übereinstimmt, und erfordert keine Polyfills, um im IE zu funktionieren.
scoota269
5

Ein vereinfachter Oneliner: 1

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

1 indexOf für Arrays wird vom IE (natürlich) nicht unterstützt. Dafür gibt es im Netz viele Affenfelder.

KooiInc
quelle
1
Das Problem mit den Wortgrenzen besteht darin, dass einige gültige Zeichen für Klassennamen, wie sie -als Wortgrenzen betrachtet werden. ZB suchen foound die Klasse ist foo-barErträge true.
Felix Kling
Du hast recht. Das Original wurde entfernt und ein weiterer Ansatz hinzugefügt. Immer noch ein Oneliner.
KooiInc
5

Das ist ein bisschen alt, aber vielleicht findet jemand meine Lösung hilfreich:

// 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;
    }
}
Dementic
quelle
benutze: 'element.hasClass (' Klassenname ');
Dementic
Warum haben Sie t.length >>> 0 verwendet? Soweit ich weiß, ist es ein Noop, wenn Sie '0' verwenden, oder?
Vitor Canova
Wow so viel Code für etwas Einfaches. Warum nicht einen regulären Ausdruck verwenden und das Rad nicht neu erfinden? Sie könnten einfach /^class_name_you_are_searching_for$/.test(myElement.className)
pqsk
1
Ich habe das zu schnell geschrieben. Um meinen regulären Ausdruck nicht zu komplizieren, wäre es /\s*class_name_you_are_searching_for\s*/.test(myElement.className)
pqsk
@pqsk - Ich schreibe meine eigenen Bibliotheken für die zukünftige Verwendung. und das fügt nur meinem Stapel hinzu. Natürlich würden andere Lösungen funktionieren, dies ist nur mein bevorzugter Weg
Dementic
4

classNameist nur eine Zeichenfolge, sodass Sie mit der regulären Funktion indexOf prüfen können, ob die Liste der Klassen eine andere Zeichenfolge enthält.

David
quelle
1
Was ist mit dem Testen auf Klasse classim obigen Beispiel?
Felix Kling
6
Erfahrungsgemäß kann diese Methode sehr riskant sein: Sie gibt true zurück, wenn Sie nach der Klasse foofür ein Element suchen, das die foobarKlasse enthält.
Zirak
2
Sicher, Sie müssen nur wissen, was Sie testen. Felix 'Code funktioniert gut, indem Leerzeichen als Trennzeichen verwendet werden.
David
Verschachtelte Instanzen eines Klassennamens können nicht berücksichtigt werden. Beispiel: 'end' befindet sich im Klassennamen 'frontend'.
Anthony Rutledge
4

Ich kenne viele Antworten, aber die meisten sind für zusätzliche Funktionen und zusätzliche Klassen. Dies ist die, die ich persönlich benutze; viel sauberer und viel weniger Codezeilen!

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}
TheBlackBenzKid
quelle
1
Diese Methode kann falsch positive <body class="category-page">document.body.className.match('page')page
Ergebnisse zurückgeben,
Kann \bzB mit aufgelöst werden /\bpage\b/g, da es sich um Regex handelt (Hinweis: muss verwendet werden / /g).
Andrew
2

Hier ist eine triviale Lösung, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird:

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;
}
Anders Fjeldstad
quelle
2

Wenn das Element nur einen Klassennamen hat, können Sie ihn schnell überprüfen, indem Sie das Klassenattribut abrufen. Die anderen Antworten sind viel robuster, aber dies hat sicherlich Anwendungsfälle.

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

}
Brandon Brule
quelle
2

Ich habe eine Prototypmethode erstellt, die classList, wenn möglich, auf Folgendes zurückgreift 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>

Testseite

vsync
quelle
Gibt es einen Grund, warum Sie die Klassenliste anstelle des Index von e.className verwenden möchten? Scheint, als ob die Leistung weniger gut ist
Ced
@Ced - Nun, Perf ist irrelevant, wenn Sie nicht Tausende von Elementen auf ihre Klasse testen (es wird wahrscheinlich in Zukunft in Browsern überarbeitet). Es ist eleganter zu verwenden, weil der Code seine Funktionalität beschreibt, aber unter dem Strich spielt es keine Rolle, machen Sie, was Sie wollen :)
vsync
1
  1. Felix 'Trick, Leerzeichen hinzuzufügen, um den Klassennamen und die gesuchte Zeichenfolge zu flankieren, ist der richtige Ansatz, um festzustellen, ob die Elemente die Klasse haben oder nicht.

  2. Um je nach Klasse ein unterschiedliches Verhalten zu erzielen, können Sie Funktionsreferenzen oder Funktionen in einer Karte verwenden:

    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) durchläuft die Schlüssel in der fns-Map.
    • Wenn nach fnsi keine Unterbrechung vorliegt, kann der Code immer dann ausgeführt werden, wenn eine Übereinstimmung vorliegt. Wenn also das Element fi, class1 und class2 enthält, werden sowohl fn1 als auch fn2 ausgeführt.
    • Der Vorteil dieses Ansatzes besteht darin, dass der für jede Klasse auszuführende Code wie der in der switch-Anweisung beliebig ist. In Ihrem Beispiel haben alle Fälle einen ähnlichen Vorgang ausgeführt, aber morgen müssen Sie möglicherweise für jeden Fall unterschiedliche Schritte ausführen.
    • Sie können den Standardfall simulieren, indem Sie eine Statusvariable angeben, ob in der Schleife eine Übereinstimmung gefunden wurde oder nicht.
entonio
quelle
1

Ich würde Poly die classList-Funktionalität füllen und die neue Syntax verwenden. Auf diese Weise verwendet ein neuerer Browser die neue Implementierung (die viel schneller ist) und nur alte Browser nehmen den Leistungseinbruch aus dem Code.

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

Eric Young
quelle
1

Dies ist ein bisschen anders, aber wenn Sie ein Ereignis haben, das den Wechsel auslöst, können Sie auf Klassen verzichten:

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

Du kannst tun

$('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, '') entfernt Ziffern von id .

Es ist ein bisschen hackig, funktioniert aber für lange Schalter ohne zusätzliche Funktionen oder Schleifen

Arthur Tarasov
quelle
1

Unter diesem Codepen-Link können Sie ein Element schneller und einfacher überprüfen, wenn es eine bestimmte Klasse hat. Verwenden Sie dazu Vanille-JavaScript ~!

hasClass (Vanilla JS)

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

Dies wird auf IE8 + unterstützt.

Zuerst prüfen wir, ob classListdies der Fall ist, und können die containsvon IE10 + unterstützte Methode verwenden. Wenn wir mit IE9 oder 8 arbeiten, wird auf einen regulären Ausdruck zurückgegriffen, der nicht so effizient ist, aber eine prägnante Polyfüllung darstellt.

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

Wenn Sie mit babel kompilieren, können Sie alternativ einfach Folgendes verwenden: el.classList.contains(className);

Aber
quelle
0

Probier diese:

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;
};
Jimy
quelle
1
Seien Sie vorsichtig mit der Wortgrenze. Es stimmt auch mit true überein, wenn Sie zB eine Klasse haben foo-barund nach suchen foo.
Felix Kling
1
Hallo Jimy, also habe ich nach diesem \ b-Metazeichen gesucht und es werden nur [ a-zA-Z0-9_] als Wortzeichen betrachtet. Für Klassennamen mit einem Minuszeichen funktioniert dies also nicht .
Stano
0

Ich denke, dass die perfekte Lösung dies sein wird

if ($(this).hasClass("your_Class")) 
    alert("positive");            
else              
    alert("Negative");
Abhishek
quelle
8
1. "Verwenden von einfachem JavaScript (nicht jQuery)" 2. Verwenden Sie Klammern
nkmol
3 - verwenden Sie Klammer
TheBlackBenzKid
0

In welchem ​​Element befindet sich derzeit die Klasse '.bar'? Hier ist eine andere Lösung, aber es liegt an Ihnen.

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 Demo

Natürlich ist dies nur eine Suche nach 1 einfachen Element <img>( /Image/g), aber Sie können alles in ein Array wie <li>is /LI/g, <ul>= /UL/gusw. einfügen .

Thielicious
quelle
0

Nur um die Antwort für Personen zu ergänzen, die versuchen, Klassennamen in Inline-SVG-Elementen zu finden.

Ändern Sie die hasCLass()Funktion in:

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

Anstatt die classNameEigenschaft zu verwenden, müssen Sie die getAttribute()Methode verwenden, um den Klassennamen abzurufen.

Ben Rudolph
quelle
0

Ich habe diese Funktionen für meine Website erstellt, ich verwende nur Vanille-Javascript, vielleicht hilft es jemandem. Zuerst habe ich eine Funktion erstellt, um ein beliebiges HTML-Element abzurufen:

//return an HTML element by ID, class or tag name
    var getElement = function(selector) {
        var elements = [];
        if(selector[0] == '#') {
            elements.push(document.getElementById(selector.substring(1, selector.length)));
        } else if(selector[0] == '.') {
            elements = document.getElementsByClassName(selector.substring(1, selector.length));
        } else {
            elements = document.getElementsByTagName(selector);
        }
        return elements;
    }

Dann die Funktion, die die zu entfernende Klasse erhält, und die Auswahl des Elements:

var hasClass = function(selector, _class) {
        var elements = getElement(selector);
        var contains = false;
        for (let index = 0; index < elements.length; index++) {
            const curElement = elements[index];
            if(curElement.classList.contains(_class)) {
                contains = true;
                break;
            }
        }
        return contains;
    }

Jetzt können Sie es so verwenden:

hasClass('body', 'gray')
hasClass('#like', 'green')
hasClass('.button', 'active')

Hoffe es wird helfen.

Josh
quelle
0

Tipp: Versuchen Sie, Abhängigkeiten von jQuery in Ihren Projekten so weit wie möglich zu entfernen - VanillaJS .

document.firstElementChildGibt das <html>Tag zurück, dann gibt das classListAttribut alle hinzugefügten Klassen zurück.

if(document.firstElementChild.classList.contains("your-class")){
    // <html> has 'your-class'
} else {
    // <html> doesn't have 'your-class'
}
Alireza
quelle
-1

Für mich ist der eleganteste und schnellste Weg, dies zu erreichen:

function hasClass(el,cl){
   return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}
Pinonirvana
quelle