0

我正在创建一些小的添加/删除/切换/具有类功能,它们都工作得很好,直到我在一个类上有多个相同类名值的实例。

这是我目前所处的位置,您会看到我的removeClass 正则表达式中有'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/

4

4 回答 4

1

您期望类字符串始终被空格包围。一旦匹配了空格,就无法再次匹配。因此,如果有两个james类彼此相邻并由一个空格隔开,则第一个james将匹配并窃取空格。然后第二个james不匹配。
要解决问题,请*在每个括号后添加。它代表零个或多个前面的元素

新正则表达式('(\s|^) ' + 类名 + '(\s|$) ', 'g')

这是你的更新小提琴:http: //jsfiddle.net/8urPs/1/

更新

根据您对多个空格的评论 - 问题是替换值。在第一种方法中,我保持不变 - $2。实际上,我们不需要替换中的任何内容,因此我们可以简单地将其更改为空字符串

this.className = this.className.replace(new RegExp('(\\s|^)*' + className + '(\\s|$)*', 'g'), '');

这是更正的小提琴:http: //jsfiddle.net/8urPs/2/

于 2013-11-08T10:25:16.333 回答
0

您有重叠表达式的问题。您正在更换james;但是,在 中james james,中间空间是共享的,并且正则表达式不会匹配重叠的跨度。

重写以使用单词边界 ( \b) 代替空格和 beg/end,或者使用前瞻以避免占用该空间。

于 2013-11-08T10:25:11.563 回答
0

这是因为类名之间的空格只能是单个匹配项的一部分。要解决此问题,您可以将最终捕获组替换为正向前瞻,如下所示:

Element.prototype.removeClass = function (className) {
    if (this.hasClass(className)) {
        this.className = this.className.replace(new RegExp('(\\s|^)' + className + '(?=\\s|$)', 'g'), '');
    }
};
于 2013-11-08T10:27:20.797 回答
0

className 后面的空格总是匹配的,以后就不能再匹配了。使用积极的前瞻断言可以帮助您:

this.className = this.className.replace(new RegExp('(\\s|^)' + className + '(?=\\s|$)', 'g'), '');

当您开始捕获组时,?=它将被视为断言并且不匹配。

工作样本:http: //jsfiddle.net/ah3Ge/

于 2013-11-08T10:29:55.247 回答