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*");

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, '');

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();

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


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

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>​]

Seit jQuery v1.4 ist dies der beste Ansatz.
Dinei


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");

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_');

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

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, '');

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(),'');});

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

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, '');

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

-6
$("#element").removeAttr("class").addClass("yourClass");

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
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.