删除所有以某个字符串开头的类

Posted

技术标签:

【中文标题】删除所有以某个字符串开头的类【英文标题】:Remove all classes that begin with a certain string 【发布时间】:2010-09-08 15:20:49 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

单词边界上的正则表达式拆分 \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();

【讨论】:

这比使用 RegExp 和 \b (字边界检查)更好的方法,因为它可以防止“僵尸类”弹出。如果您有“前缀-后缀”之类的类,则此线程中的“最佳答案”将离开“-后缀”类,因为 \b 将在“-”字符之前拆分。您的 split-map-join 解决方案可以解决这个问题 :) 我围绕您的解决方案 Kabir 创建了一个小型 jQuery 插件:(gist.github.com/2881585) +1 我也同意,其他所有答案似乎只是一个简单的正则表达式,会在非空格单词边界上中断。如果我明天有时间,我会提供一个单元测试来证明这一点。 我喜欢它,虽然这实际上不是有效代码,因为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(" ")); 更有效的解决方案使用地图:$e.attr('class', $.map($e.attr('class').split(' '), function (klass) return klass.indexOf(prefix) != 0 ? klass : undefined; ).join(' ')); 这种方法效果最好。我使用了@JakubP 的插件。如果可以的话,一个建议是:它做什么,当它现在返回类时,它会产生很多空间。例如,如果您运行 removeClassPrefix("black");class="blackRow blackText orangeFace blackHead" 将返回 class=" orangeFace "。我通过像这样修剪结果来解决这个问题:el.className = $.trim(classes.join(" "));.【参考方案2】:

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

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

【讨论】:

小心这个。破折号('-')和点等的单词边界分割,所以类名如“bg.a”、“bg-a”等不会被删除,而是用“.a”、“-a”等替换. 所以如果你有带有标点符号的类名,你可能会因为运行一个简单的正则表达式替换而遇到麻烦。这是一个 SO 线程about word boundary definition Kabir Sarin 在下面的 split(' ') 和 indexOf 的回答是更好的 IMO,因为它不会导致那些特殊字符的“僵尸”类弹出。 这种方法仍然可以与更好的正则表达式一起使用,例如在这里找到的那​​个:***.com/a/2644364/1333402【参考方案3】:

我写了一个简单的jQuery plugin - alterClass,它可以删除通配符类。 也可以选择添加类。

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

【讨论】:

谢谢皮特!刚刚使用了你的插件,效果很好......节省了我一些时间!【参考方案4】:

你不需要任何 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;

【讨论】:

如果前缀以破折号结尾,则需要更改正则表达式。 new RegExp('\\b' + prefix + '[\\S]*\\b', 'g')【参考方案5】:

使用2nd signature 的$.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 开始,这是最好的方法。【参考方案6】:

对于现代浏览器:

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

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

【讨论】:

使用 string.starsWith()(或 string.endsWith())对我来说是完美的!【参考方案7】:

我会使用简单的 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");

【讨论】:

【参考方案8】:

http://www.mail-archive.com/jquery-en@googlegroups.com/msg03998.html 说:

...和 ​​.removeClass() 将删除所有类...

它对我有用;)

干杯

【讨论】:

这是一个更好的选择!工作。 该问题没有询问如何删除所有类,而是询问如何删除以某个字符串开头的所有类。这两件事非常非常不同。【参考方案9】:

我正在寻找完全相同的问题的解决方案。删除所有以前缀“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 倍,并且“字符串以”检查的效率较低:-/【参考方案10】:

在一行中... 删除所有匹配正则表达式 someRegExp

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

【讨论】:

【参考方案11】:

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

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

【讨论】:

2020年,劣势是jQuery。【参考方案12】:

Prestaul 的回答很有帮助,但对我来说不太奏效。通过 id 选择对象的 jQuery 方法不起作用。我不得不使用

document.getElementById("a").className

而不是

$("#a").className

【讨论】:

或 $("#a")[0].className 因为 className 仅在 DOM 元素上可用,在 jQuery 对象上不可用 这是对某人回答的评论,不是回答【参考方案13】:

我还使用连字符'-' 和数字作为类名。所以我的版本包括'\d-'

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

【讨论】:

【参考方案14】:
(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);

【讨论】:

【参考方案15】:

对于那些只需要 jQuery 解决方案的人来说,转换为 jQuery 的最佳答案:

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

【讨论】:

【参考方案16】:
$("#element").removeAttr("class").addClass("yourClass");

【讨论】:

我认为您没有很好地阅读这个问题。用户询问的不是简单地删除一个类并添加另一个类。 @Andrew Barber:你说得对,这不是正确的答案,但majorsk8 建议如何清除所有类(removeAttr),而不仅仅是一个;)

以上是关于删除所有以某个字符串开头的类的主要内容,如果未能解决你的问题,请参考以下文章

删除名称以某个字符串开头的所有表

递归删除所有以

jQuery或CSS选择器选择以某个字符串开头的所有ID [重复]

python 正则表达式,怎样匹配以某个字符串开头,以某个字符串结尾的情况?

js 判断一个字符是不是以某个字符串开头

LINQ:选择任何字符串以某个字符开头的行