Wie füge ich eine Klasse in JavaScript hinzu oder entferne sie?


75

Da element.classListwird nicht in IE 9 und Safari-5 unterstützt, was eine Alternative Cross-Browser - Lösung?

Bitte keine Frameworks .

Die Lösung muss mindestens in IE 9 , Safari 5 , FireFox 4, Opera 11.5 und Chrome funktionieren.

Verwandte Beiträge (enthält aber keine Lösung):

  1. Hinzufügen und Entfernen von CSS-Klassen

  2. Hinzufügen und Entfernen einer Klasse mit Animation

  3. Klasse entfernen Klasse hinzufügen?


6
Ich werde nie die Notwendigkeit eines browserübergreifenden Codes und die Weigerung verstehen, ein Framework zu verwenden. Das ist genau ihr Zweck. Es ist, als würde man versuchen, Spaghetti zu essen, sich aber weigern, eine Gabel zu benutzen. Sicher, man kommt durch, aber es ist chaotisch.
David

2
@ David gibt es einen Unterschied zwischen Frameworks und Shims. Unterlegscheiben sind ebenfalls gültig.
Raynos

1
@ Raynos, meistens ist das, was Sie denken, nur ein Shim, fünf, was zu viel weniger wartbarem, weniger getestetem Code führt, der besser durch ein Framework ersetzt werden sollte.
David

4
@davin Du brauchst nur eine Unterlegscheibe. Es heißt DOM Shim. Dann schreiben Sie einfach standardkonformen Code. Sie benötigen ein Framework, das als DOM bezeichnet wird.
Raynos

23
@davin, weil das Essen von Spaghetti mit einer Gabel nicht bedeutet, dass Sie nicht verstehen dürfen, wie eine Gabel funktioniert.
Pacerier

Antworten:


15

Eine Möglichkeit, mit Klassen ohne Frameworks / Bibliotheken herumzuspielen, wäre die Verwendung der Eigenschaft Element.className, die " den Wert des Klassenattributs des angegebenen Elements abruft und festlegt " (aus der MDN-Dokumentation ).
Wie @ matías-fidemraizer bereits in seiner Antwort erwähnt hat, können Sie nach Erhalt der Klassenzeichenfolge für Ihr Element alle mit Zeichenfolgen verknüpften Methoden verwenden, um es zu ändern.

Hier ein Beispiel:
Angenommen, Sie haben ein Div mit der ID "myDiv" und möchten die Klasse "main__section" hinzufügen, wenn der Benutzer darauf klickt.

window.onload = init;

function init() {
  document.getElementById("myDiv").onclick = addMyClass;
}

function addMyClass() {
  var classString = this.className; // returns the string of all the classes for myDiv
  var newClass = classString.concat(" main__section"); // Adds the class "main__section" to the string (notice the leading space)
  this.className = newClass; // sets className to the new string
}

11
Wie kann dies die akzeptierte Antwort sein, wenn die Frage die Klasse "Entfernen" enthält, diese Antwort jedoch nicht?
Motin

7
.replace (/ \ bexmaple \ b /, "")
leafiy

Dies funktioniert nicht für ein SVG-Element, das mit "createElementNS" erstellt wurde. Wie kann dies erreicht werden?
Neoexpert

62

Hier ist die Lösung für addClass, removeClass, hasClass in einer reinen Javascript-Lösung.

Eigentlich ist es von http://jaketrent.com/post/addremove-classes-raw-javascript/

function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className += " "+cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className=ele.className.replace(reg,' ');
  }
}

33

Ich habe gerade Folgendes geschrieben:

function addClass(el, classNameToAdd){
    el.className += ' ' + classNameToAdd;   
}

function removeClass(el, classNameToRemove){
    var elClass = ' ' + el.className + ' ';
    while(elClass.indexOf(' ' + classNameToRemove + ' ') !== -1){
         elClass = elClass.replace(' ' + classNameToRemove + ' ', '');
    }
    el.className = elClass;
}

Ich denke, sie werden in allen Browsern funktionieren.


Dies funktioniert nicht, zum Beispiel, wenn Sie versuchen, die einzige Klasse auf einem Element zu entfernen (das auf beiden Seiten seines Namens kein Leerzeichen hat)
Gareth

@ Gareth, das wird funktionieren. In Zeile 1 von removeClass wird auf jeder Seite ein Leerzeichen eingefügt.
Paul

6
Das wird nicht funktionieren. Wenn das Element die Klasse 'abc' hat und Sie versuchen, b zu entfernen, wird die neue Klasse auf 'ac' gesetzt. So müssen Sie ändern , ''indem ' 'in der replaceFunktion. Darüber hinaus ist class ein reserviertes Schlüsselwort.
Bali Balo

1
Ich habe Ihre Lösung auf 1 festgelegt. Verwenden Sie nicht "Klasse", ein reserviertes Wort. 2. Ihre fehlerhafte removeClassMethode, die nach wiederholtem Gebrauch Unmengen an Unordnung verursacht, da Leerzeichen nicht gekürzt werden. Siehe Antwort unten als Antwort.
Drew

Ich habe diesen Code mit dem Hinzufügen dieses Codes direkt nach der Ersetzungsanweisung verwendet: while (elClass[0] === " ") elClass = elClass.substr(1); while (elClass[elClass.length - 1] === " ") elClass = elClass.substr(0, elClass.length - 1);Dadurch wird der führende und nachfolgende Leerzeichen gelöscht, der möglicherweise noch vorhanden ist
Filip Cornelissen

24

Schauen Sie sich diese Oneliner an:

  1. Klasse entfernen:

    element.classList.remove('hidden');
    
  2. Klasse umschalten (fügt die Klasse hinzu, falls sie noch nicht vorhanden ist, und entfernt sie, falls vorhanden)

    element.classList.toggle('hidden');
    

Das ist alles! Ich habe einen Test gemacht - 10000 Iterationen. 0,8s.


Beachten Sie, dass classList in IE 9 nicht unterstützt wird, was in der Frage von OP angegeben ist
Warren Spencer

2
Es befriedigt zwar keine Einschränkung, die für OP äußerst spezifisch war, aber ich denke, diese Frage wird von vielen Menschen betrachtet, die auf eine Antwort auf die allgemeine Frage ohne diese spezifischen Einschränkungen hoffen. Ich war sehr froh, dies zu finden und bemerkte es erst bei meinem zweiten Besuch. Ich bin froh, dass ich es getan habe - viel sauberere Lösung. Vielen Dank!
Kyle Baker

18

Am einfachsten ist es, element.classListdie hat remove(name), add(name), toggle(name), und contains(name)Methoden und wird nun von allen gängigen Browsern unterstützt .

Für ältere Browser ändern Sie element.className. Hier sind zwei Helfer:

function addClass(element, className){
    element.className += ' ' + className;   
}

function removeClass(element, className) {
    element.className = element.className.replace(
        new RegExp('( |^)' + className + '( |$)', 'g'), ' ').trim();
}

Dies funktioniert nicht für ein SVG-Element, das mit "createElementNS" erstellt wurde. Wie kann dies erreicht werden?
Neoexpert

10

Lesen Sie diesen Artikel im Mozilla Developer Network:

Da die Eigenschaft element.className vom Typ string ist, können Sie reguläre String- Objektfunktionen verwenden, die in jeder JavaScript-Implementierung enthalten sind:

  • Wenn Sie eine Klasse hinzufügen möchten, verwenden Sie diese zuerst, String.indexOfum zu überprüfen, ob die Klasse in className vorhanden ist . Wenn es nicht vorhanden ist, verknüpfen Sie einfach ein leeres Zeichen und den neuen Klassennamen mit dieser Eigenschaft. Wenn es vorhanden ist, tun Sie nichts.

  • Wenn Sie eine Klasse entfernen möchten, verwenden Sie einfach String.replace"[className]" durch eine leere Zeichenfolge. Zum Schluss String.trimentfernen Sie leere Zeichen am Anfang und Ende von element.className.


5

Die Lösung von @Paulpro wurde behoben

  1. Verwenden Sie nicht "Klasse", da es sich um ein reserviertes Wort handelt
  2. removeClass Die Funktion war defekt, da sie nach wiederholtem Gebrauch fehlerhaft war.

`

function addClass(el, newClassName){
    el.className += ' ' + newClassName;   
}

function removeClass(el, removeClassName){
    var elClass = el.className;
    while(elClass.indexOf(removeClassName) != -1) {
        elClass = elClass.replace(removeClassName, '');
        elClass = elClass.trim();
    }
    el.className = elClass;
}

Sollten Sie nicht überprüfen, ob der Klassenname vorhanden ist, bevor Sie ihn hinzufügen?
JoeTidee

if(el.className.indexOf(' ' + className) != -1) return;zu addClasswürde helfen
Keaton

4

Die Lösung ist zu

Shim .classList:

Verwenden Sie entweder die DOM-Unterlegscheibe oder die Unterlegscheibe von Eli Grey unten

Haftungsausschluss: Ich glaube, die Unterstützung ist FF3.6 +, Opera10 +, FF5, Chrome, IE8 +

/*
 * classList.js: Cross-browser full element.classList implementation.
 * 2011-06-15
 *
 * By Eli Grey, http://eligrey.com
 * Public Domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */

/*global self, document, DOMException */

/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/

if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {

(function (view) {

"use strict";

var
      classListProp = "classList"
    , protoProp = "prototype"
    , elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
    , objCtr = Object
    , strTrim = String[protoProp].trim || function () {
        return this.replace(/^\s+|\s+$/g, "");
    }
    , arrIndexOf = Array[protoProp].indexOf || function (item) {
        var
              i = 0
            , len = this.length
        ;
        for (; i < len; i++) {
            if (i in this && this[i] === item) {
                return i;
            }
        }
        return -1;
    }
    // Vendors: please allow content code to instantiate DOMExceptions
    , DOMEx = function (type, message) {
        this.name = type;
        this.code = DOMException[type];
        this.message = message;
    }
    , checkTokenAndGetIndex = function (classList, token) {
        if (token === "") {
            throw new DOMEx(
                  "SYNTAX_ERR"
                , "An invalid or illegal string was specified"
            );
        }
        if (/\s/.test(token)) {
            throw new DOMEx(
                  "INVALID_CHARACTER_ERR"
                , "String contains an invalid character"
            );
        }
        return arrIndexOf.call(classList, token);
    }
    , ClassList = function (elem) {
        var
              trimmedClasses = strTrim.call(elem.className)
            , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
            , i = 0
            , len = classes.length
        ;
        for (; i < len; i++) {
            this.push(classes[i]);
        }
        this._updateClassName = function () {
            elem.className = this.toString();
        };
    }
    , classListProto = ClassList[protoProp] = []
    , classListGetter = function () {
        return new ClassList(this);
    }
;
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i) {
    return this[i] || null;
};
classListProto.contains = function (token) {
    token += "";
    return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function (token) {
    token += "";
    if (checkTokenAndGetIndex(this, token) === -1) {
        this.push(token);
        this._updateClassName();
    }
};
classListProto.remove = function (token) {
    token += "";
    var index = checkTokenAndGetIndex(this, token);
    if (index !== -1) {
        this.splice(index, 1);
        this._updateClassName();
    }
};
classListProto.toggle = function (token) {
    token += "";
    if (checkTokenAndGetIndex(this, token) === -1) {
        this.add(token);
    } else {
        this.remove(token);
    }
};
classListProto.toString = function () {
    return this.join(" ");
};

if (objCtr.defineProperty) {
    var classListPropDesc = {
          get: classListGetter
        , enumerable: true
        , configurable: true
    };
    try {
        objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
    } catch (ex) { // IE 8 doesn't support enumerable:true
        if (ex.number === -0x7FF5EC54) {
            classListPropDesc.enumerable = false;
            objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
        }
    }
} else if (objCtr[protoProp].__defineGetter__) {
    elemCtrProto.__defineGetter__(classListProp, classListGetter);
}

}(self));

}

1
Auf jeden Fall eine clevere Unterlegscheibe. Es funktioniert in FF mindestens bis zu 1,5 (kann darunter nicht getestet werden). Es bricht in IE7 und darunter. Aus diesem Grund ist es auf realen Websites für alles Wesentliche nahezu nutzlos. Verwenden Sie für den realen Gebrauch ein Framework.
Theazureshadow

@theazureshadow psh, Legacy-Support ist für Unternehmenslösungen gedacht, die sich außerhalb der Unternehmenswelt für IE7 interessieren.
Raynos

Wenn Sie sich für die 12 Prozent der Benutzer interessieren (ungefähr einer von acht), die derzeit IE7 und niedriger verwenden (Quelle: Marketshare.hitslink.com ). Ich denke, iOS 5 ist die erste iOS-Version, die es ebenfalls unterstützt. Zum Zeitpunkt Ihrer Veröffentlichung würden also keine iPhone-Benutzer unterstützt. Sprechen Sie über Vermächtnis!
Theazureshadow

1
@theazureshadow meh, IE7 benötigt kein Javascript. Und Handys ist ein ganz anderes Ballspiel. (Die Unterlegscheibe sollte auf Handys funktionieren)
Raynos

Sie haben Recht mit Mobile. Es wird wirklich im Einzelfall liegen, ob sich die IE7-Unterstützung lohnt. Die meisten Leute werden es leicht wert finden, ein Framework zu verwenden, um Browserunterschiede auszugleichen - weit über die Verfügbarkeit von classList hinaus. "IE7 braucht kein Javascript" ist eine äußerst fragwürdige Aussage.
Theazureshadow

3

Verbesserte Version von Emils Code (mit trim ())

function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className = ele.className.trim() + " " + cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className = ele.className.replace(reg,' ');
    ele.className = ele.className.trim();
  }
}

2
function addClass(element, classString) {
    element.className = element
        .className
        .split(' ')
        .filter(function (name) { return name !== classString; })
        .concat(classString)
        .join(' ');
}

function removeClass(element, classString) {
    element.className = element
        .className
        .split(' ')
        .filter(function (name) { return name !== classString; })
        .join(' ');
}

2

Nur für den Fall, dass jemand Prototypfunktionen für Elemente erstellen lassen möchte, verwende ich diese Option, wenn ich Klassen verschiedener Objekte bearbeiten muss:

Element.prototype.addClass = function (classToAdd) {
  var classes = this.className.split(' ')
  if (classes.indexOf(classToAdd) === -1) classes.push(classToAdd)
  this.className = classes.join(' ')
}

Element.prototype.removeClass = function (classToRemove) {
  var classes = this.className.split(' ')
  var idx =classes.indexOf(classToRemove)
  if (idx !== -1) classes.splice(idx,1)
  this.className = classes.join(' ')
}

Verwenden Sie sie wie: document.body.addClass('whatever')oderdocument.body.removeClass('whatever')

Anstelle von body können Sie auch jedes andere Element verwenden (div, span, Sie nennen es)


0

CSS-Klassen hinzufügen: cssClassesStr += cssClassName;

CSS-Klassen entfernen: cssClassStr = cssClassStr.replace(cssClassName,"");

Attribut 'Klassen' hinzufügen: object.setAttribute("class", ""); //pure addition of this attribute

Attribut entfernen: object.removeAttribute("class");


0

Ein leicht verständlicher Weg:

// Add class 
DOMElement.className += " one";
// Example:
// var el = document.body;
// el.className += " two"

// Remove class 
function removeDOMClass(element, className) {
    var oldClasses      = element.className,
        oldClassesArray = oldClasses.split(" "),
        newClassesArray = [],
        newClasses;

    // Sort
    var currentClassChecked,
        i;     
    for ( i = 0; i < oldClassesArray.length; i++ ) { 
        // Specified class will not be added in the new array
        currentClassChecked = oldClassesArray[i];
        if( currentClassChecked !== className ) { 
            newClassesArray.push(currentClassChecked);
        }
    }

    // Order 
    newClasses = newClassesArray.join(" ");

    // Apply     
    element.className = newClasses;

    return element;

}
// Example:
// var el = document.body;
// removeDOMClass(el, "two")

https://gist.github.com/sorcamarian/ff8db48c4dbf4f5000982072611955a2

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.