Brad
Brad

Reputation: 6105

Remove all classes that begin with a certain string

I have a div with id="a" that may have any number of classes attached to it, from several groups. Each group has a specific prefix. In the javascript, I don't know which class from the group is on the div. I want to be able to clear all classes with a given prefix and then add a new one. If I want to remove all of the classes that begin with "bg", how do I do that? Something like this, but that actually works:

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

Upvotes: 118

Views: 118074

Answers (17)

Scott Chambers
Scott Chambers

Reputation: 611

This is a fairly old post. But I worked out a solution that worked for me.

$('[class*=classtoremove]').each(function( index ) {
    var classArray = $(this).attr('class').split(' ');
    $.each( classArray, function( key, value ) {
        if(value.includes('classtoremove')) {
            console.log(value);
            $('.' + value).removeClass(value);
        }
    });
});

Essentially it will get any class that contains classtoremove regardless what is added on the end. So it could be classtoremove234164726 or classtoremove767657576575 it will find the two classes, split all the classes then for each class thats in the array will check to see if the value includes the class to remove. it then gets that class and removes the class without having to replace or re-add anything.

$('[class*=classtoremove]').each(function( index ) {
    var classArray = $(this).attr('class').split(' ');
    $.each( classArray, function( key, value ) {
        if(value.includes('classtoremove')) {
            console.log(value + ' has been removed');
            $('.' + value).removeClass(value);
        }
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class='classtoremove235235235 chicken omlets wrapper'></div>
<div class='classtoremove354645745 chicken omlets wrapper'></div>
<div class='classtoremoveesdfdfh5645 chicken omlets wrapper'></div>
<div class='classtoremove3425423wdt chicken omlets wrapper'></div>
<div class='classtoremovewdgrt346 chicken omlets wrapper'></div>
<div class='classtoremovesdgsbfd4454 chicken omlets wrapper'></div>
<div class='classtoremove45454545 chicken omlets wrapper'></div>
<div class='classtoremove666eed chicken omlets wrapper'></div>

Upvotes: 1

danday74
danday74

Reputation: 56966

The top answer converted to jQuery for those wanting a jQuery only solution:

const prefix = 'prefix'
const classes = el.attr('class').split(' ').filter(c => !c.startsWith(prefix))
el.attr('class', classes.join(' ').trim())

Upvotes: 0

Kabir Sarin
Kabir Sarin

Reputation: 18526

A regex splitting on word boundary \b isn't the best solution for this:

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

or as a 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();

Upvotes: 120

Max
Max

Reputation: 621

For modern browsers:

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

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

Upvotes: 6

Pete B
Pete B

Reputation: 1729

I've written a simple jQuery plugin - alterClass, that does wildcard class removal. Will optionally add classes too.

$( '#foo' ).alterClass( 'foo-* bar-*', 'foobar' ) 

Upvotes: 34

Adam111p
Adam111p

Reputation: 3717

In one line ... Removes all classes that match a regular expression someRegExp

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

Upvotes: 3

Pat
Pat

Reputation: 36702

With jQuery, the actual DOM element is at index zero, this should work

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

Upvotes: 63

user4661317
user4661317

Reputation:

An approach I would use using simple jQuery constructs and array handling functions, is to declare an function that takes id of the control and prefix of the class and deleted all classed. The code is attached:

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

Now this function can be called from anywhere, onclick of button or from code:

removeclasses("a","bg");

Upvotes: 4

Pawel
Pawel

Reputation: 18222

I was looking for solution for exactly the same problem. To remove all classes starting with prefix "fontid_" After reading this article I wrote a small plugin which I'm using now.

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

Usage:

$('#elementId').removePrefixedClasses('prefix-of-classes_');

Upvotes: 3

abernier
abernier

Reputation: 28208

Using 2nd signature of $.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>​]

Upvotes: 10

majorsk8
majorsk8

Reputation: 19

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

Upvotes: -5

Rob
Rob

Reputation: 11368

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

Upvotes: 1

Jan.J
Jan.J

Reputation: 3080

I know it's an old question, but I found out new solution and want to know if it has disadvantages?

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

Upvotes: 2

jamland
jamland

Reputation: 971

I also use hyphen'-' and digits for class name. So my version include '\d-'

$('#a')[0].className = $('#a')[0].className.replace(/\bbg.\d-*?\b/g, '');

Upvotes: 1

Ivan
Ivan

Reputation:

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

...and .removeClass() would remove all classes...

It works for me ;)

cheers

Upvotes: 3

Brad
Brad

Reputation: 6105

Prestaul's answer was helpful, but it didn't quite work for me. The jQuery way to select an object by id didn't work. I had to use

document.getElementById("a").className

instead of

$("#a").className

Upvotes: 1

Prestaul
Prestaul

Reputation: 85145

You don't need any jQuery specific code to handle this. Just use a RegExp to replace them:

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

You can modify this to support any prefix but the faster method is above as the RegExp will be compiled only once:

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

Upvotes: 14

Related Questions