javascript - 正则表达式更改 html 元素类与 javascript 不工作

标签 javascript html css regex

我有以下 javascript 函数可以在 onclick 事件中打开和关闭子列表元素:

function ShowHideDtls(itId) {
    var subMen = document.getElementById(itId);
    if (subMen != null) {
        if (subMen.className == "nav nav-second-level collapse in") {
            subMen.className = "nav nav-second-level collapse";
        } else {
            subMen.className += " in";
        }
    }
}

“collapse”是一个使 display=none 隐藏子列表的 css 类,“in”是一个使 display=block 显示子列表的类,创建一个带有子菜单的菜单。

我在这个问题中找到了Change an element's class with JavaScript在第一个(接受的)答案中使用正则表达式来执行此操作。我这样试过:

function ShowHideDtls(itId) {
    var subMen = document.getElementById(itId);
    if (subMen != null) {
        if (subMen.className.match(/(?:^|\s)in(?!\S)/)) {
            subMen.className.replace(/(?:^|\s)in(?!\S)/g, '');
        } else {
            subMen.className += " in";
        }
    }
}

没有正则表达式的代码可以完美运行,但有正则表达式则不能。我检查了 regex101.com 中的正则表达式,它似乎在那里工作。据我所知,使用正则表达式比使用所有类名的长字符串更合适,而且我还有一个导航三级类,我必须关闭和打开它,所以正则表达式似乎是方便和正确的方法做吧。 怎么了? 谢谢。

最佳答案

这里不需要regex。您可以使用 classList

Using classList is a convenient alternative to accessing an element's list of classes as a space-delimited string via element.className.

function ShowHideDtls(itId) {
    var subMen = document.getElementById(itId);
    if (subMen != null) {
        subMen.classList.toggle('in');
    }
}

toggle() 将切换元素的类。如果元素已经有类,它将删除它,如果没有,则切换会将类添加到元素。

检查 Browser Compatibility .

您可以使用以下 SHIM来自 MDN对于 IE9,

/* 
 * classList.js: Cross-browser full element.classList implementation.
 * 2014-07-23
 *
 * By Eli Grey, http://eligrey.com
 * Public Domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */

/*global self, document, DOMException */

/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/

if ("document" in self) {

    // Full polyfill for browsers with no classList support
    if (!("classList" in document.createElement("_"))) {

        (function (view) {

            "use strict";

            if (!('Element' in view)) return;

            var
                classListProp = "classList",
                protoProp = "prototype",
                elemCtrProto = view.Element[protoProp],
                objCtr = Object,
                strTrim = String[protoProp].trim || function () {
                    return this.replace(/^\s+|\s+$/g, "");
                },
                arrIndexOf = Array[protoProp].indexOf || function (item) {
                    var
                        i = 0,
                        len = this.length;
                    for (; i < len; i++) {
                        if (i in this && this[i] === item) {
                            return i;
                        }
                    }
                    return -1;
                }
                // Vendors: please allow content code to instantiate DOMExceptions
                ,
                DOMEx = function (type, message) {
                    this.name = type;
                    this.code = DOMException[type];
                    this.message = message;
                },
                checkTokenAndGetIndex = function (classList, token) {
                    if (token === "") {
                        throw new DOMEx(
                            "SYNTAX_ERR", "An invalid or illegal string was specified"
                        );
                    }
                    if (/\s/.test(token)) {
                        throw new DOMEx(
                            "INVALID_CHARACTER_ERR", "String contains an invalid character"
                        );
                    }
                    return arrIndexOf.call(classList, token);
                },
                ClassList = function (elem) {
                    var
                        trimmedClasses = strTrim.call(elem.getAttribute("class") || ""),
                        classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [],
                        i = 0,
                        len = classes.length;
                    for (; i < len; i++) {
                        this.push(classes[i]);
                    }
                    this._updateClassName = function () {
                        elem.setAttribute("class", this.toString());
                    };
                },
                classListProto = ClassList[protoProp] = [],
                classListGetter = function () {
                    return new ClassList(this);
                };
            // Most DOMException implementations don't allow calling DOMException's toString()
            // on non-DOMExceptions. Error's toString() is sufficient here.
            DOMEx[protoProp] = Error[protoProp];
            classListProto.item = function (i) {
                return this[i] || null;
            };
            classListProto.contains = function (token) {
                token += "";
                return checkTokenAndGetIndex(this, token) !== -1;
            };
            classListProto.add = function () {
                var
                    tokens = arguments,
                    i = 0,
                    l = tokens.length,
                    token, updated = false;
                do {
                    token = tokens[i] + "";
                    if (checkTokenAndGetIndex(this, token) === -1) {
                        this.push(token);
                        updated = true;
                    }
                }
                while (++i < l);

                if (updated) {
                    this._updateClassName();
                }
            };
            classListProto.remove = function () {
                var
                    tokens = arguments,
                    i = 0,
                    l = tokens.length,
                    token, updated = false,
                    index;
                do {
                    token = tokens[i] + "";
                    index = checkTokenAndGetIndex(this, token);
                    while (index !== -1) {
                        this.splice(index, 1);
                        updated = true;
                        index = checkTokenAndGetIndex(this, token);
                    }
                }
                while (++i < l);

                if (updated) {
                    this._updateClassName();
                }
            };
            classListProto.toggle = function (token, force) {
                token += "";

                var
                    result = this.contains(token),
                    method = result ?
                    force !== true && "remove" :
                    force !== false && "add";

                if (method) {
                    this[method](token);
                }

                if (force === true || force === false) {
                    return force;
                } else {
                    return !result;
                }
            };
            classListProto.toString = function () {
                return this.join(" ");
            };

            if (objCtr.defineProperty) {
                var classListPropDesc = {
                    get: classListGetter,
                    enumerable: true,
                    configurable: true
                };
                try {
                    objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
                } catch (ex) { // IE 8 doesn't support enumerable:true
                    if (ex.number === -0x7FF5EC54) {
                        classListPropDesc.enumerable = false;
                        objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
                    }
                }
            } else if (objCtr[protoProp].__defineGetter__) {
                elemCtrProto.__defineGetter__(classListProp, classListGetter);
            }

        }(self));

    } else {
        // There is full or partial native classList support, so just check if we need
        // to normalize the add/remove and toggle APIs.

        (function () {
            "use strict";

            var testElement = document.createElement("_");

            testElement.classList.add("c1", "c2");

            // Polyfill for IE 10/11 and Firefox <26, where classList.add and
            // classList.remove exist but support only one argument at a time.
            if (!testElement.classList.contains("c2")) {
                var createMethod = function (method) {
                    var original = DOMTokenList.prototype[method];

                    DOMTokenList.prototype[method] = function (token) {
                        var i, len = arguments.length;

                        for (i = 0; i < len; i++) {
                            token = arguments[i];
                            original.call(this, token);
                        }
                    };
                };
                createMethod('add');
                createMethod('remove');
            }

            testElement.classList.toggle("c3", false);

            // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
            // support the second argument.
            if (testElement.classList.contains("c3")) {
                var _toggle = DOMTokenList.prototype.toggle;

                DOMTokenList.prototype.toggle = function (token, force) {
                    if (1 in arguments && !this.contains(token) === !force) {
                        return force;
                    } else {
                        return _toggle.call(this, token);
                    }
                };

            }

            testElement = null;
        }());

    }

}

如果您正在使用 jQuery,您可以使用 toggleClass():

function ShowHideDtls(itId) {
    $('#' + itId).toggleClass('in');
}

编辑

如果您仍想使用 regex:

if (/\bin\b/.test(subMen.className))
    subMen.className.replace(/\bin\b/, '');
} else {
    subMen.className += " in";
}

您还可以使用 split()indexOf 来检查元素上是否存在类。

var classes = className.split(/\s+/),
    classIndex = classes.indexOf('in');
if (classIndex > -1) {
    classes.splice(classIndex, 1);
    subMen.className = classes.join(' ');
} else {
    subMen.className += " in";
}

关于javascript - 正则表达式更改 html 元素类与 javascript 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31939994/

相关文章:

javascript - 响应 jQuery post 请求而设置的变量

php - 多复选框,可以选中所有和取消选中所有

php - 使用 Simple Html Dom 通过 ajax 动态加载 Scrape Div 的内容

html - 内表值的置换

html - 有没有办法强制一个类在另一个元素之后显示而不隐藏它?

javascript - 既然 JavaScript 有闭包,那么 this 关键字的目的到底是什么?

javascript - 使用 jQuery 将完整 html anchor 替换为另一个 html anchor

javascript - 如何在 asp.net 中使用 JavaScript 只打印表数据元素?

javascript - Margin-top/Padding-top 没有效果?

在 iis 中托管后 CSS 不引用