如何在JavaScript中添加/删除类?


75

由于element.classListIE 9和Safari-5不支持,因此有什么替代的跨浏览器解决方案?

没有框架

解决方案必须至少在IE 9Safari 5,FireFox 4,Opera 11.5和Chrome中运行。

相关文章(但不包含解决方案):

  1. 如何添加和删除CSS类

  2. 用动画添加和删除类

  3. 添加删除课程?


6
我永远不会理解跨浏览器兼容代码的需求以及拒绝使用框架的需求。那是他们的目的。这就像尝试吃意大利面,但拒绝使用叉子,确保您可以通过,但杂乱无章。
戴文2011年

2
@davin框架和垫片之间有区别。垫片也有效。
雷诺斯2011年

1
@Raynos,在大多数情况下,您认为只是一个垫片而最终却是五个垫片,这导致可维护性,测试性降低的代码少得多,而最好用框架代替。
戴文,2011年

4
@davin您只需要一个垫片。它称为DOM填充程序。然后,您只需编写符合标准的代码。您确实需要一个框架,它称为DOM。
雷诺斯2011年

24
@davin,因为用叉子吃意大利面并不意味着您不了解叉子的工作原理。
Pacerier,2011年

Answers:


15

处理没有框架/库的类的一种方法是使用Element.className属性,该属性“获取并设置指定元素的class属性的值。 ”(来自MDN文档)。
正如@matías-fidemraizer在他的回答中已经提到的那样,一旦获得了元素的类字符串,就可以使用与字符串关联的任何方法对其进行修改。

举个例子:
假设您有一个ID为“ myDiv”的div,并且您想在用户单击该类时为其添加“ main__section”类,

window.onload = init;

function init() {
  document.getElementById("myDiv").onclick = addMyClass;
}

function addMyClass() {
  var classString = this.className; // returns the string of all the classes for myDiv
  var newClass = classString.concat(" main__section"); // Adds the class "main__section" to the string (notice the leading space)
  this.className = newClass; // sets className to the new string
}

11
这怎么可能是被接受的答案,那么问题包括“删除”课,但这个答案不行吗?
Motin

7
.replace(/ \ bexmaple \ b /,“”)
叶2015年

这不适用于使用“ createElementNS”创建的svg元素。如何做到这一点?
neoexpert

62

这是纯javascript解决方案中addClass,removeClass,hasClass的解决方案。

实际上是从http://jaketrent.com/post/addremove-classes-raw-javascript/

function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className += " "+cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className=ele.className.replace(reg,' ');
  }
}

33

我只写了这些:

function addClass(el, classNameToAdd){
    el.className += ' ' + classNameToAdd;   
}

function removeClass(el, classNameToRemove){
    var elClass = ' ' + el.className + ' ';
    while(elClass.indexOf(' ' + classNameToRemove + ' ') !== -1){
         elClass = elClass.replace(' ' + classNameToRemove + ' ', '');
    }
    el.className = elClass;
}

我认为它们可以在所有浏览器中使用。


这是行不通的,例如,如果您尝试删除元素上的唯一类(其名称的两边都没有空格)
Gareth

@Gareth,它将起作用。它在removeClass的第一行的每一侧插入一个空格。
保罗

6
那不管用。如果element具有类“ abc”,并且您尝试删除b,它将把新类设置为“ ac”。所以,你必须改变''通过' 'replace功能。而且,class是保留关键字。
巴厘岛Balo

1
我已经将您的解决方案固定为1.不使用“类”,这是一个保留字。2.您的removeClass方法已损坏,由于没有修剪空白而在重复使用后会产生大量混乱。
德鲁

我在replace语句之后使用了此代码,并加上了以下代码:while (elClass[0] === " ") elClass = elClass.substr(1); while (elClass[elClass.length - 1] === " ") elClass = elClass.substr(0, elClass.length - 1);这将删除可能仍然存在的前导和尾随空间
Filip Cornelissen

25

看一下这些单线:

  1. 删除课程:

    element.classList.remove('hidden');
    
  2. 切换类(如果尚不存在,则添加该类;如果不存在,则将其删除)

    element.classList.toggle('hidden');
    

就这样!我做了一个测试-10000次迭代。0.8秒


请注意,IE 9中不支持classList,这在OP的问题中已阐明
Warren Spencer

2
尽管它不能满足OP所特有的限制,但我认为许多人都希望看到这个问题,而他们却希望在没有这些特定限制的情况下回答一般问题。我很高兴找到这个,直到第二次才发现它。我很高兴自己做了-更干净的解决方案。谢谢!
凯尔·贝克

18

最简单的是element.classList它有remove(name)add(name)toggle(name),和contains(name)方法,现在所有的主流浏览器的支持

对于较旧的浏览器,您需要更改element.className。这里有两个助手:

function addClass(element, className){
    element.className += ' ' + className;   
}

function removeClass(element, className) {
    element.className = element.className.replace(
        new RegExp('( |^)' + className + '( |$)', 'g'), ' ').trim();
}

这不适用于使用“ createElementNS”创建的svg元素。如何做到这一点?
neoexpert

10

阅读此Mozilla开发人员网络文章:

由于element.className属性的类型为字符串,因此可以使用任何JavaScript实现中的常规String对象函数:

  • 如果要添加类,请首先使用String.indexOf以检查className中是否存在类。如果不存在,只需将一个空白字符和新的类名连接到此属性。如果存在,则什么也不做。

  • 如果要删除一个类,只需使用String.replace,用一个空字符串替换“ [className]”。最后使用String.trim删除开头和结尾的空白字符element.className


5

修复了@Paulpro的解决方案

  1. 不要使用“类”,因为它是保留字
  2. removeClass 该功能已损坏,因为它在重复使用后会出错。

`

function addClass(el, newClassName){
    el.className += ' ' + newClassName;   
}

function removeClass(el, removeClassName){
    var elClass = el.className;
    while(elClass.indexOf(removeClassName) != -1) {
        elClass = elClass.replace(removeClassName, '');
        elClass = elClass.trim();
    }
    el.className = elClass;
}

在添加类之前,您是否应该检查类名是否存在?
JoeTidee

if(el.className.indexOf(' ' + className) != -1) return;addClass会帮助
基顿

4

解决方案是

垫片.classList

请使用DOM垫片或下面的Eli Grey垫片

免责声明:我相信支持为FF3.6 +,Opera10 +,FF5,Chrome,IE8 +

/*
 * classList.js: Cross-browser full element.classList implementation.
 * 2011-06-15
 *
 * 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 (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {

(function (view) {

"use strict";

var
      classListProp = "classList"
    , protoProp = "prototype"
    , elemCtrProto = (view.HTMLElement || 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.className)
            , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
            , i = 0
            , len = classes.length
        ;
        for (; i < len; i++) {
            this.push(classes[i]);
        }
        this._updateClassName = function () {
            elem.className = 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 (token) {
    token += "";
    if (checkTokenAndGetIndex(this, token) === -1) {
        this.push(token);
        this._updateClassName();
    }
};
classListProto.remove = function (token) {
    token += "";
    var index = checkTokenAndGetIndex(this, token);
    if (index !== -1) {
        this.splice(index, 1);
        this._updateClassName();
    }
};
classListProto.toggle = function (token) {
    token += "";
    if (checkTokenAndGetIndex(this, token) === -1) {
        this.add(token);
    } else {
        this.remove(token);
    }
};
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));

}

1
绝对是一个聪明的垫片。它至少可以在FF下以FF工作(不能测试到1.5以下)。在IE7及以下版本中会中断。因此,它在实际网站上几乎是无用的。为了真正使用,请使用框架。
theazureshadow 2011年

@theazureshadow psh,旧版支持适用于企业解决方案,他们在企业领域之外关心IE7。
雷诺斯2011年

如果您关心当前使用IE7及以下版本的12%的用户(大约八分之一)(来源:marketshare.hitslink.com)。我认为iOS 5也是第一个支持它的iOS版本,因此在您发帖时,不支持iPhone用户。谈论遗产!
theazureshadow 2011年

1
@theazureshadow meh,IE7不需要javascript。手机是完全不同的球类游戏。(垫片应在手机上工作)
Raynos 2011年

您对手机的看法是正确的。是否值得IE7支持取决于个别情况。大多数人会发现使用框架消除浏览器差异很容易,这很值得-远远超出了classList的可用性。“ IE7不需要javascript”是一个非常有问题的陈述。
theazureshadow 2011年

3

emil代码的改进版本(带有trim())

function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className = ele.className.trim() + " " + cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className = ele.className.replace(reg,' ');
    ele.className = ele.className.trim();
  }
}

2
function addClass(element, classString) {
    element.className = element
        .className
        .split(' ')
        .filter(function (name) { return name !== classString; })
        .concat(classString)
        .join(' ');
}

function removeClass(element, classString) {
    element.className = element
        .className
        .split(' ')
        .filter(function (name) { return name !== classString; })
        .join(' ');
}

2

万一有人想为元素构建原型函数,这就是我需要操纵不同对象的类时使用的方法:

Element.prototype.addClass = function (classToAdd) {
  var classes = this.className.split(' ')
  if (classes.indexOf(classToAdd) === -1) classes.push(classToAdd)
  this.className = classes.join(' ')
}

Element.prototype.removeClass = function (classToRemove) {
  var classes = this.className.split(' ')
  var idx =classes.indexOf(classToRemove)
  if (idx !== -1) classes.splice(idx,1)
  this.className = classes.join(' ')
}

像这样使用它们: document.body.addClass('whatever')document.body.removeClass('whatever')

除了body,您还可以使用其他任何元素(div,span,您可以为其命名)


0

添加CSS类: cssClassesStr += cssClassName;

删除CSS类: cssClassStr = cssClassStr.replace(cssClassName,"");

添加属性“类”: object.setAttribute("class", ""); //pure addition of this attribute

删除属性: object.removeAttribute("class");


0

一种易于理解的方式:

// Add class 
DOMElement.className += " one";
// Example:
// var el = document.body;
// el.className += " two"

// Remove class 
function removeDOMClass(element, className) {
    var oldClasses      = element.className,
        oldClassesArray = oldClasses.split(" "),
        newClassesArray = [],
        newClasses;

    // Sort
    var currentClassChecked,
        i;     
    for ( i = 0; i < oldClassesArray.length; i++ ) { 
        // Specified class will not be added in the new array
        currentClassChecked = oldClassesArray[i];
        if( currentClassChecked !== className ) { 
            newClassesArray.push(currentClassChecked);
        }
    }

    // Order 
    newClasses = newClassesArray.join(" ");

    // Apply     
    element.className = newClasses;

    return element;

}
// Example:
// var el = document.body;
// removeDOMClass(el, "two")

https://gist.github.com/sorcamarian/ff8db48c4dbf4f5000982072611955955

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.