Entfernen Sie alle Klassen, die mit einer bestimmten Zeichenfolge beginnen

99

Ich habe eine Div mit einer id="a"beliebigen Anzahl von Klassen aus mehreren Gruppen. Jede Gruppe hat ein bestimmtes Präfix. Im Javascript weiß ich nicht, welche Klasse aus der Gruppe auf der Div ist. Ich möchte in der Lage sein, alle Klassen mit einem bestimmten Präfix zu löschen und dann eine neue hinzuzufügen. Wie mache ich das, wenn ich alle Klassen entfernen möchte, die mit "bg" beginnen? So etwas, aber das funktioniert tatsächlich:

$("#a").removeClass("bg*");
Brad
quelle

Antworten:

59

Bei jQuery befindet sich das eigentliche DOM-Element auf dem Index Null. Dies sollte funktionieren

$('#a')[0].className = $('#a')[0].className.replace(/\bbg.*?\b/g, '');
Klopfen
quelle
34
Vorsicht mit diesem. Wortgrenzen werden auf Strichzeichen ('-') und Punkte und andere aufgeteilt, sodass Klassennamen wie "bg.a", "bg-a" usw. nicht entfernt, sondern durch ".a", "-a" usw. Ersetzt werden Wenn Sie also Klassennamen mit Interpunktionszeichen haben, können Probleme auftreten, wenn Sie nur eine einfache Regex-Ersetzung ausführen. Hier ist ein SO-Thread über die Definition von Wortgrenzen
Jakub P.
6
Kabir Sarins Antwort unten mit split ('') und indexOf ist IMO besser, da diese speziellen "Zombie" -Klassen dadurch nicht auftauchen.
Jakub P.
2
Diese Methode kann immer noch mit einem besseren regulären
Ausdruck
109

Eine Regex-Aufteilung an der Wortgrenze \bist hierfür nicht die beste Lösung:

var prefix = "prefix";
var classes = el.className.split(" ").filter(function(c) {
    return c.lastIndexOf(prefix, 0) !== 0;
});
el.className = classes.join(" ").trim();

oder als jQuery-Mixin:

$.fn.removeClassPrefix = function(prefix) {
    this.each(function(i, el) {
        var classes = el.className.split(" ").filter(function(c) {
            return c.lastIndexOf(prefix, 0) !== 0;
        });
        el.className = $.trim(classes.join(" "));
    });
    return this;
};

2018 ES6 Update:

const prefix = "prefix";
const classes = el.className.split(" ").filter(c => !c.startsWith(prefix));
el.className = classes.join(" ").trim();
Sarink
quelle
9
Dies ist ein besserer Ansatz als die Verwendung von RegExp mit \ b (Wortgrenzenprüfung), da dadurch verhindert wird, dass "Zombieklassen" auftauchen. Wenn Sie Klassen wie "Präfix-Suffix" haben, verlässt die 'beste Antwort' in diesem Thread die Klasse '-suffix', da \ b vor '-' char aufgeteilt wird. Ihre Split-Map-Join-Lösung umgeht das :) Ich habe ein winziges jQuery-Plugin um Ihre Lösung erstellt, Kabir: ( gist.github.com/2881585 )
Jakub P.
3
+1 Ich stimme ebenfalls zu, jede andere Antwort scheint nur eine einfache Regex zu sein, die an Nicht-Raum-Wortgrenzen brechen würde. Wenn ich morgen Zeit habe, werde ich einen Unit-Test liefern, der dies beweist.
Gerges
1
Ich mag es, obwohl dies eigentlich kein gültiger Code ist, da die anonyme Funktion in filtereinen Booleschen Wert zurückgeben muss. Dies wird funktionieren:var classes = $(e).attr("class").split(" "); $(classes).each(function(i, item) { classes[i] = item.indexOf("prefix") === -1 ? item : "prefix-new"); }); $(e).attr("class", classes.join(" "));
Tim
Eine valideere Lösung verwendet Karte:$e.attr('class', $.map($e.attr('class').split(' '), function (klass) { return klass.indexOf(prefix) != 0 ? klass : undefined; }).join(' '));
M Miller
2
Dieser Ansatz funktioniert am besten. Ich habe das Plugin von @ JakubP verwendet. Ein Vorschlag, wenn ich darf: Was es tut, wenn es jetzt die Klassen zurückgibt, verursacht es viel Platz. Zum Beispiel class="blackRow blackText orangeFace blackHead"wird zurückkehren, class=" orangeFace "wenn Sie ausführen removeClassPrefix("black");. Ich habe dies gelöst, indem ich das Ergebnis wie folgt gekürzt habe : el.className = $.trim(classes.join(" "));.
Albert
29

Ich habe ein einfaches jQuery-Plugin geschrieben - alterClass , das Platzhalterklassen entfernt. Fügt optional auch Klassen hinzu.

$( '#foo' ).alterClass( 'foo-* bar-*', 'foobar' ) 
Pete B.
quelle
Danke Pete! Habe gerade dein Plugin benutzt und es funktioniert super ... hat mir etwas Zeit gespart!
Jordan.baucke
11

Sie benötigen dafür keinen jQuery-spezifischen Code. Verwenden Sie einfach ein RegExp, um sie zu ersetzen:

$("#a").className = $("#a").className.replace(/\bbg.*?\b/g, '');

Sie können dies ändern, um jedes Präfix zu unterstützen. Die schnellere Methode ist jedoch oben aufgeführt, da RegExp nur einmal kompiliert wird:

function removeClassByPrefix(el, prefix) {
    var regx = new RegExp('\\b' + prefix + '.*?\\b', 'g');
    el.className = el.className.replace(regx, '');
    return el;
}
Prestaul
quelle
9

Mit 2. Unterschrift von $.fn.removeClass:

// Considering:
var $el = $('<div class="  foo-1 a b foo-2 c foo"/>');

function makeRemoveClassHandler(regex) {
  return function (index, classes) {
    return classes.split(/\s+/).filter(function (el) {return regex.test(el);}).join(' ');
  }
}

$el.removeClass(makeRemoveClassHandler(/^foo-/));
//> [<div class=​"a b c foo">​</div>​]
abernier
quelle
Seit jQuery v1.4 ist dies der beste Ansatz.
Dinei
3

http://www.mail-archive.com/[email protected]/msg03998.html sagt:

... und .removeClass () würden alle Klassen entfernen ...

Für mich geht das ;)

Prost


quelle
Dies ist eine bessere Wahl! Funktioniert.
Afshin Mehrabani
12
Die Frage fragt nicht, wie alle Klassen entfernt werden sollen, sondern wie alle Klassen entfernt werden sollen, die mit einer bestimmten Zeichenfolge beginnen. Diese beiden Dinge sind sehr, sehr unterschiedlich.
Chris Harrison
3

Ein Ansatz, den ich mit einfachen jQuery-Konstrukten und Array-Handling-Funktionen verwenden würde, besteht darin, eine Funktion zu deklarieren, die die ID des Steuerelements und das Präfix der Klasse übernimmt und alle klassifizierten löscht. Der Code ist beigefügt:

function removeclasses(controlIndex,classPrefix){
    var classes = $("#"+controlIndex).attr("class").split(" ");
    $.each(classes,function(index) {
        if(classes[index].indexOf(classPrefix)==0) {
            $("#"+controlIndex).removeClass(classes[index]);
        }
    });
}

Jetzt kann diese Funktion von überall, per Knopfdruck oder per Code aufgerufen werden:

removeclasses("a","bg");
nhahtdh
quelle
2

Ich suchte nach einer Lösung für genau das gleiche Problem. So entfernen Sie alle Klassen, die mit dem Präfix "fontid_" beginnen Nach dem Lesen dieses Artikels habe ich ein kleines Plugin geschrieben, das ich jetzt verwende.

(function ($) {
        $.fn.removePrefixedClasses = function (prefix) {
            var classNames = $(this).attr('class').split(' '),
                className,
                newClassNames = [],
                i;
            //loop class names
            for(i = 0; i < classNames.length; i++) {
                className = classNames[i];
                // if prefix not found at the beggining of class name
                if(className.indexOf(prefix) !== 0) {
                    newClassNames.push(className);
                    continue;
                }
            }
            // write new list excluding filtered classNames
            $(this).attr('class', newClassNames.join(' '));
        };
    }(fQuery));

Verwendung:

$('#elementId').removePrefixedClasses('prefix-of-classes_');
Pawel
quelle
Dies ist nichts weiter als meine Lösung mit 10x mehr Zeilen und einem weniger effizienten "String beginnt mit" check: - /
sarink
2

Für moderne Browser:

let element = $('#a')[0];
let cls = 'bg';

element.classList.remove.apply(element.classList, Array.from(element.classList).filter(v=>v.startsWith(cls)));
Max
quelle
1

Ich weiß, dass es eine alte Frage ist, aber ich habe eine neue Lösung gefunden und möchte wissen, ob sie Nachteile hat.

$('#a')[0].className = $('#a')[0].className
                              .replace(/(^|\s)bg.*?(\s|$)/g, ' ')
                              .replace(/\s\s+/g, ' ')
                              .replace(/(^\s|\s$)/g, '');
Jan.J.
quelle
1

In einer Zeile ... Entfernt alle Klassen, die einem regulären Ausdruck someRegExp entsprechen

$('#my_element_id').removeClass( function() { return (this.className.match(/someRegExp/g) || []).join(' ').replace(prog.status.toLowerCase(),'');});
Adam111p
quelle
0

Prestaul's Antwort war hilfreich, aber es hat bei mir nicht ganz funktioniert. Die jQuery-Methode zum Auswählen eines Objekts anhand der ID hat nicht funktioniert. Ich musste benutzen

document.getElementById("a").className

anstatt

$("#a").className
Brad
quelle
oder $ ("# a") [0] .className als className ist nur für das DOM-Element verfügbar und nicht für das jQuery-Objekt
Naeem Sarfraz
Dies ist ein Kommentar für jemandes Antwort, keine Antwort
TJ
0

Ich benutze auch Bindestrich und Ziffern für den Klassennamen. Meine Version enthält also '\ d-'

$('#a')[0].className = $('#a')[0].className.replace(/\bbg.\d-*?\b/g, '');
Jamland
quelle
0
(function($)
{
    return this.each(function()
    {
        var classes = $(this).attr('class');

        if(!classes || !regex) return false;

        var classArray = [];

        classes = classes.split(' ');

        for(var i=0, len=classes.length; i<len; i++) if(!classes[i].match(regex)) classArray.push(classes[i]);

        $(this).attr('class', classArray.join(' '));
    });
})(jQuery);
rauben
quelle
-6
$("#element").removeAttr("class").addClass("yourClass");
majorsk8
quelle
3
Ich glaube nicht, dass Sie die Frage sehr gut gelesen haben. Der Benutzer wollte nicht einfach eine Klasse entfernen und eine weitere hinzufügen.
Andrew Barber
1
@ Andrew Barber: Sie haben Recht, dies ist nicht die richtige Antwort, aber Majorsk8 schlug vor, alle Klassen zu löschen (removeAttr), nicht nur eine einzige;)
Tilt