删除所有以某个字符串开头的类
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 [重复]