删除所有以特定字符串开头的类


99

我有一个div,id="a"其中可能有来自多个组的任何数量的类。每个组都有一个特定的前缀。在javascript中,我不知道该群组中的哪个类位于div上。我希望能够清除具有给定前缀的所有类,然后添加一个新的类。如果要删除所有以“ bg”开头的类,该怎么做?像这样的东西,但实际上有效:

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

Answers:


59

使用jQuery,实际的DOM元素的索引为零,这应该可以工作

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

34
小心这一点。单词边界在破折号('-')和点等上分开,因此不会删除类名,例如“ bg.a”,“ bg-a”等,而是替换为“ .a”,“-a”等因此,如果您使用带有标点符号的类名,则可能仅通过运行简单的正则表达式替换就遇到麻烦了。这是关于单词边界定义
Jakub P.

6
下面的Kabir Sarin用split('')和indexOf的答案是更好的IMO,因为它不会引起那些特殊字符“僵尸”类的出现。
Jakub P.

2
此方法仍可与更好的正则表达式一起使用,例如在此处找到的正则表达式:stackoverflow.com/a/2644364/1333402
ssmith

109

在单词边界上进行正则表达式分割\b不是解决此问题的最佳方法:

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

或作为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更新:

const prefix = "prefix";
const classes = el.className.split(" ").filter(c => !c.startsWith(prefix));
el.className = classes.join(" ").trim();

9
这比将RegExp与\ b(字边界检查)配合使用是更好的方法,因为它可以防止弹出“僵尸类”。如果您有类似“前缀后缀”的类,则该线程中的“最佳答案”将保留类“-后缀”,因为\ b将在“-”字符前分割。您的split-map-join解决方案可以解决此问题:)我围绕您的解决方案创建了一个小jQuery插件Kabir:(gist.github.com/2881585
Jakub P.

3
我也同意+1,其他所有答案似乎都是一个简单的正则表达式,它将在非空间字边界上中断。如果明天有时间,我将提供证明这一点的单元测试。
吉尔吉斯2012年

1
我喜欢它,尽管这实际上不是有效的代码,因为in中的匿名函数filter必须返回布尔值。这将起作用: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

一个更有效的解决方案使用地图:$e.attr('class', $.map($e.attr('class').split(' '), function (klass) { return klass.indexOf(prefix) != 0 ? klass : undefined; }).join(' '));
米勒

2
这种方法效果最好。我使用了@JakubP的插件。如果可能的话,我的一个建议是:它的作用是,当它现在返回类时,会占用大量空间。例如,如果您运行,class="blackRow blackText orangeFace blackHead"它将返回。我通过调整结果来解决此问题,如下所示:。class=" orangeFace "removeClassPrefix("black");el.className = $.trim(classes.join(" "));
艾伯特


11

您不需要任何jQuery特定代码即可处理此问题。只需使用RegExp来替换它们:

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

您可以修改它以支持任何前缀,但是更快的方法在上面,因为RegExp将仅编译一次:

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

9

使用第二个签名$.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>​]

从jQuery v1.4开始,这是最好的方法。
Dinei 2015年


3

我将使用简单的jQuery构造和数组处理函数使用的一种方法是声明一个函数,该函数接受控件的ID和类的前缀并删除所有已分类的类。附带的代码:

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

现在可以在任何地方,单击按钮或从代码中调用此函数:

removeclasses("a","bg");

2

我一直在寻找完全相同的问题的解决方案。删除所有以前缀“ fontid_”开头的类。阅读本文后,我编写了一个小插件,该插件现在正在使用。

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

用法:

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

这无非是我的解决方案,它的行数增加了10倍,效率较低的“字符串开头”检查:-/
2014年

2

对于现代浏览器:

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

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

1

我知道这是一个老问题,但是我找到了新的解决方案,想知道它是否有缺点?

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

1

一行...删除所有与正则表达式匹配的类someRegExp

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

0

Prestaul的回答很有帮助,但对我而言并不奏效。通过id选择对象的jQuery方法无效。我不得不用

document.getElementById("a").className

代替

$("#a").className

或$(“#a”)[0] .className作为className仅在DOM元素上可用,而在jQuery对象上不可用
Naeem Sarfraz

这是对某人答案的评论,而不是答案
TJ

0

我还使用连字符'-'和数字作为类名。所以我的版本包括'\ 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
我认为您不太清楚这个问题。用户并不是想简单地删除一个类并添加另一个。
Andrew Barber

1
@Andrew Barber:你是对的,这不是正确的答案,但是majorsk8建议了如何清除所有类(removeAttr),而不仅仅是单个的类;)
倾斜
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.