html – jQuery removeClass wildcard

The Question :

383 people think this question is useful

Is there any easy way to remove all classes matching, for example,

color-*

so if I have an element:

<div id="hello" class="color-red color-brown foo bar"></div>

after removing, it would be

<div id="hello" class="foo bar"></div>

Thanks!

The Question Comments :

The Answer 1

702 people think this answer is useful

The removeClass function takes a function argument since jQuery 1.4.

$("#hello").removeClass (function (index, className) {
    return (className.match (/(^|\s)color-\S+/g) || []).join(' ');
});

Live example: http://jsfiddle.net/xa9xS/1409/

The Answer 2

101 people think this answer is useful
$('div').attr('class', function(i, c){
    return c.replace(/(^|\s)color-\S+/g, '');
});

The Answer 3

51 people think this answer is useful

I’ve written a plugin that does this called alterClass – Remove element classes with wildcard matching. Optionally add classes: https://gist.github.com/1517285

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

The Answer 4

15 people think this answer is useful

I’ve generalized this into a Jquery plugin which takes a regex as an argument.

Coffee:

$.fn.removeClassRegex = (regex) ->
  $(@).removeClass (index, classes) ->
    classes.split(/\s+/).filter (c) ->
      regex.test c
    .join ' '

Javascript:

$.fn.removeClassRegex = function(regex) {
  return $(this).removeClass(function(index, classes) {
    return classes.split(/\s+/).filter(function(c) {
      return regex.test(c);
    }).join(' ');
  });
};

So, for this case, usage would be (both Coffee and Javascript):

$('#hello').removeClassRegex(/^color-/)

Note that I’m using the Array.filter function which doesn’t exist in IE<9. You could use Underscore’s filter function instead or Google for a polyfill like this WTFPL one.

The Answer 5

12 people think this answer is useful

If you want to use it in other places I suggest you an extension. This one is working fine for me.

 $.fn.removeClassStartingWith = function (filter) {
    $(this).removeClass(function (index, className) {
        return (className.match(new RegExp("\\S*" + filter + "\\S*", 'g')) || []).join(' ')
    });
    return this;
};

Usage:

$(".myClass").removeClassStartingWith('color');

The Answer 6

5 people think this answer is useful

A generic function that remove any class starting with begin:

function removeClassStartingWith(node, begin) {
    node.removeClass (function (index, className) {
        return (className.match ( new RegExp("\\b"+begin+"\\S+", "g") ) || []).join(' ');
    });
}

http://jsfiddle.net/xa9xS/2900/

var begin = 'color-';

function removeClassStartingWith(node, begin) {
    node.removeClass (function (index, className) {
        return (className.match ( new RegExp("\\b"+begin+"\\S+", "g") ) || []).join(' ');
    });
}

removeClassStartingWith($('#hello'), 'color-');

console.log($("#hello")[0].className);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hello" class="color-red color-brown foo bar"></div>

The Answer 7

4 people think this answer is useful

we can get all the classes by .attr("class"), and to Array, And loop & filter:

var classArr = $("#sample").attr("class").split(" ")
$("#sample").attr("class", "")
for(var i = 0; i < classArr.length; i ++) {
    // some condition/filter
    if(classArr[i].substr(0, 5) != "color") {
        $("#sample").addClass(classArr[i]);
    }
}

demo: http://jsfiddle.net/L2A27/1/

The Answer 8

4 people think this answer is useful

Similar to @tremby’s answer, here is @Kobi’s answer as a plugin that will match either prefixes or suffixes.

  • ex) strips btn-mini and btn-danger but not btn when stripClass("btn-").
  • ex) strips horsebtn and cowbtn but not btn-mini or btn when stripClass('btn', 1)

Code:

$.fn.stripClass = function (partialMatch, endOrBegin) {
    /// <summary>
    /// The way removeClass should have been implemented -- accepts a partialMatch (like "btn-") to search on and remove
    /// </summary>
    /// <param name="partialMatch">the class partial to match against, like "btn-" to match "btn-danger btn-active" but not "btn"</param>
    /// <param name="endOrBegin">omit for beginning match; provide a 'truthy' value to only find classes ending with match</param>
    /// <returns type=""></returns>
    var x = new RegExp((!endOrBegin ? "\\b" : "\\S+") + partialMatch + "\\S*", 'g');

    // https://stackoverflow.com/a/2644364/1037948
    this.attr('class', function (i, c) {
        if (!c) return; // protect against no class
        return c.replace(x, '');
    });
    return this;
};

https://gist.github.com/zaus/6734731

The Answer 9

4 people think this answer is useful

For a jQuery plugin try this

$.fn.removeClassLike = function(name) {
    return this.removeClass(function(index, css) {
        return (css.match(new RegExp('\\b(' + name + '\\S*)\\b', 'g')) || []).join(' ');
    });
};

or this

$.fn.removeClassLike = function(name) {
    var classes = this.attr('class');
    if (classes) {
        classes = classes.replace(new RegExp('\\b' + name + '\\S*\\s?', 'g'), '').trim();
        classes ? this.attr('class', classes) : this.removeAttr('class');
    }
    return this;
};

Edit: The second approach should be a bit faster because that runs just one regex replace on the whole class string. The first (shorter) uses jQuery’s own removeClass method which iterates trough all the existing classnames and tests them for the given regex one by one, so under the hood it does more steps for the same job. However in real life usage the difference is negligible.

Speed comparison benchmark

The Answer 10

3 people think this answer is useful

You could also do this with vanilla JavaScript using Element.classList. No need for using a regular expression either:

function removeColorClasses(element) { for (let className of Array.from(element.classList)) if (className.startsWith("color-")) element.classList.remove(className); }

Note: Notice that we create an Array copy of the classList before starting, that’s important since classList is a live DomTokenList which will update as classes are removed.

The Answer 11

2 people think this answer is useful

Based on ARS81‘s answer (that only matches class names beginning with), here’s a more flexible version. Also a hasClass() regex version.

Usage: $('.selector').removeClassRegex('\\S*-foo[0-9]+')

$.fn.removeClassRegex = function(name) {
  return this.removeClass(function(index, css) {
    return (css.match(new RegExp('\\b(' + name + ')\\b', 'g')) || []).join(' ');
  });
};

$.fn.hasClassRegex = function(name) {
  return this.attr('class').match(new RegExp('\\b(' + name + ')\\b', 'g')) !== null;
};

The Answer 12

2 people think this answer is useful

This will effectively remove all class names which begins with prefix from a node’s class attribute. Other answers do not support SVG elements (as of writing this), but this solution does:

$.fn.removeClassPrefix = function(prefix){
    var c, regex = new RegExp("(^|\\s)" + prefix + "\\S+", 'g');
    return this.each(function(){
        c = this.getAttribute('class');
        this.setAttribute('class', c.replace(regex, ''));
    });
};

The Answer 13

2 people think this answer is useful

I had the same issue and came up with the following that uses underscore’s _.filter method. Once I discovered that removeClass takes a function and provides you with a list of classnames, it was easy to turn that into an array and filter out the classname to return back to the removeClass method.

// Wildcard removeClass on 'color-*'
$('[class^="color-"]').removeClass (function (index, classes) {
  var
    classesArray = classes.split(' '),
    removeClass = _.filter(classesArray, function(className){ return className.indexOf('color-') === 0; }).toString();

  return removeClass;
});

The Answer 14

1 people think this answer is useful

You could also use the className property of the element’s DOM object:

var $hello = $('#hello');
$('#hello').attr('class', $hello.get(0).className.replace(/\bcolor-\S+/g, ''));

The Answer 15

1 people think this answer is useful

An alternative way of approaching this problem is to use data attributes, which are by nature unique.

You’d set the colour of an element like: $el.attr('data-color', 'red');

And you’d style it in css like: [data-color="red"]{ color: tomato; }

This negates the need for using classes, which has the side-effect of needing to remove old classes.

The Answer 16

0 people think this answer is useful

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

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 = classes.join(" ");
    });
    return this;
};

The Answer 17

0 people think this answer is useful

if you have more than one element having a class name ‘example’, to remove classes of ‘color-‘in all of them you can do this:[using jquery]

var objs = $('html').find('.example');
for(index=0 ; index < obj1s.length ; index++){
    objs[index].className = objs[index].className.replace(/col-[a-z1-9\-]*/,'');
}

if you don’t put [a-z1-9-]* in your regex it won’t remove the classes which have a number or some ‘-‘ in their names.

The Answer 18

0 people think this answer is useful

If you just need to remove the last set color, the following might suit you.

In my situation, I needed to add a color class to the body tag on a click event and remove the last color that was set. In that case, you store the current color, and then look up the data tag to remove the last set color.

Code:

var colorID = 'Whatever your new color is';

var bodyTag = $('body');
var prevColor = bodyTag.data('currentColor'); // get current color
bodyTag.removeClass(prevColor);
bodyTag.addClass(colorID);
bodyTag.data('currentColor',colorID); // set the new color as current

Might not be exactly what you need, but for me it was and this was the first SO question I looked at, so thought I would share my solution in case it helps anyone.

Tags:,

Add a Comment