我正在创建一些小的add / remove / toggle / has类函数,它们都运行得很好,直到我在类上有多个相同类名值的实例。
这是我到目前为止的地方,你会看到我的removeClass Regexp中有'g'标志:
Element.prototype.hasClass = function (className) {
return new RegExp('(\\s|^)' + className + '(\\s|$)').test(this.className);
};
Element.prototype.addClass = function (className) {
if (!this.hasClass(className)) {
this.className += ' ' + className;
}
};
Element.prototype.removeClass = function (className) {
if (this.hasClass(className)) {
this.className = this.className.replace(new RegExp('(\\s|^)' + className + '(\\s|$)', 'g'), '$2');
}
};
Element.prototype.toggleClass = function (className) {
if (this.hasClass(className)) {
this.removeClass(className);
} else {
this.addClass(className);
}
};
起始HTML:
<p class=" james james dean james james james">Hello</p>
渲染时:
<p class=" james dean james">Hello</p>
这是我的工作jsFiddle,如果你检查元素,你可以看到并没有删除所有 james 实例。任何人都能明白我做错了什么吗?提前致谢 :) http://jsfiddle.net/8urPs/
答案 0 :(得分:1)
您希望类字符串始终被空格包围。一旦匹配空白区域,就无法再次匹配。因此,如果有两个james
类彼此相邻并由一个空格分隔,则第一个james
将匹配并且窃取白色空间。然后第二个james
将不匹配
要解决此问题,请在每个括号后添加*
。它代表前面元素的零个或多个。
新的RegExp('(\ s | ^)'+ className +'(\ s | $)','g')
以下是您的更新小提琴:http://jsfiddle.net/8urPs/1/
根据您对多个空格的评论 - 问题是替换价值。在第一种方法中,我保持不变 - $2
。实际上,我们在替换中不需要任何内容,因此我们可以简单地将其更改为空字符串
this.className = this.className.replace(new RegExp('(\\s|^)*' + className + '(\\s|$)*', 'g'), '');
这是经过纠正的小提琴:http://jsfiddle.net/8urPs/2/
答案 1 :(得分:0)
表达式重叠时遇到问题。您正在替换james
;但是,在james james
中,中间空间是共享的,正则表达式与重叠跨度不匹配。
重写为使用单词边界(\b
)而不是空格和beg / end,或者使用lookahead,以便不占用该空间。
答案 2 :(得分:0)
这是因为类名之间的空格只能是单个匹配的一部分。要解决此问题,您可以使用正面的外观替换最终捕获组,如下所示:
Element.prototype.removeClass = function (className) {
if (this.hasClass(className)) {
this.className = this.className.replace(new RegExp('(\\s|^)' + className + '(?=\\s|$)', 'g'), '');
}
};
答案 3 :(得分:0)
className之后的空格始终匹配,然后无法再次匹配。使用正向前瞻断言可以帮助您:
this.className = this.className.replace(new RegExp('(\\s|^)' + className + '(?=\\s|$)', 'g'), '');
当您使用?=
启动捕获组时,它将作为断言进行处理并且不匹配。