jQuery removeClass通配符

有没有什么简单的方法来删除所有匹配的类,例如,

color-*

如果我有一个元素:

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

去除后,它将是

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

谢谢!

172675 次浏览
$('div').attr('class', function(i, c){
return c.replace(/(^|\s)color-\S+/g, '');
});

removeClass函数自jQuery 1.4起接受函数参数。

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

实例:http://jsfiddle.net/xa9xS/1409/

你也可以使用元素DOM对象的className属性:

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

我已经写了一个插件,做这个叫做alterClass -删除元素类通配符匹配。可选地添加类:https://gist.github.com/1517285

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

我把它概括成一个Jquery插件,它把一个正则表达式作为参数。

咖啡:

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

因此,在这种情况下,使用将是(咖啡和Javascript):

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

注意,我使用的是Array.filter函数,该函数在IE<9中不存在。你可以使用下划线的过滤函数或谷歌来代替像这个WTFPL这样的填充。

类似于@tremby的回答,这里是@Kobi的回答作为一个插件,它将匹配前缀或后缀。

  • ex)剥离btn-minibtn-danger,但当stripClass("btn-")时不剥离btn
  • ex)剥离horsebtncowbtn,但当stripClass('btn', 1)时不剥离btn-minibtn

代码:

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

在单词边界\b上进行正则表达式拆分并不是最好的解决方案:

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

或作为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;
};

我们可以通过.attr("class"),和数组,和循环&过滤器:

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/

我有同样的问题,并提出了以下使用下划线的_。过滤方法。一旦我发现removeClass接受一个函数并为您提供一个类名列表,就很容易将其转换为一个数组并过滤掉类名以返回到removeClass方法。

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

对于jQuery插件,试试这个

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

或者这个

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

编辑:第二种方法应该快一点,因为它只在整个类字符串上运行一个regex替换。第一个(更短)使用jQuery自己的removeClass方法,该方法迭代所有现有的类名,并逐个测试给定的正则表达式,因此在底层,它为相同的工作执行了更多步骤。然而,在现实生活中,这种差异是可以忽略不计的。

< a href = " https://jsbench。me/ yykhh1nl6ke /1" rel="nofollow noreferrer">速度比较基准 . me/ yykhh1nl6ke /1" rel="nofollow noreferrer">速度比较基准 . me/ yykhh1nl6ke /1

如果你有多个元素的类名为“example”,要删除所有的“color-”类,你可以这样做:

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

如果你不把[a-z1-9-]*放在你的正则表达式中,它不会删除名字中有数字或一些“-”的类。

基于ARS81回答(只匹配以开头的类名),这里有一个更灵活的版本。也是一个hasClass()正则表达式版本。

用法:$('.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;
};

这将有效地从节点的class属性中删除所有以prefix开头的类名。其他答案不支持SVG元素(在撰写本文时),但这个解决方案支持:

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

如果你只是需要去除最后一组颜色,下面的方法可能适合你。

在我的情况下,我需要在单击事件的主体标记上添加一个颜色类,并删除设置的最后一个颜色。在这种情况下,存储当前颜色,然后查找数据标记以删除最后设置的颜色。

< p >代码:

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

可能不是你需要的,但对我来说是,这是我看到的第一个SO问题,所以我想分享我的解决方案,以防它能帮助到任何人。

如果你想在其他地方使用它,我建议你扩展。这个对我来说很好。

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

用法:

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

你也可以通过使用Element.classList的普通JavaScript来做到这一点。也不需要使用正则表达式:

< p > <代码> 函数removeColorClasses(元素) { for(让数组的className从(element.classList)) 如果(className.startsWith(“颜色”)) element.classList.remove(名称); } < /代码> < / p >

注意:请注意,我们在开始之前创建了classListArray副本,这很重要,因为classList是一个活动的DomTokenList,它将随着类的删除而更新。

一个泛型函数,删除任何以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>

解决这个问题的另一种方法是使用数据属性,数据属性本质上是唯一的。

你可以像这样设置元素的颜色:$el.attr('data-color', 'red');

你可以用这样的css样式:[data-color="red"]{ color: tomato; }

这就否定了使用类的需要,这有需要删除旧类的副作用。