Javascript 有没有办法用classList在一条指令中添加/删除几个类?

Javascript 有没有办法用classList在一条指令中添加/删除几个类?,javascript,html,Javascript,Html,到目前为止,我必须这样做: elem.classList.add("first"); elem.classList.add("second"); elem.classList.add("third"); 而这在jQuery中是可行的,就像这样 $(elem).addClass("first second third"); 我想知道是否有添加或删除类的原生方法。向元素添加类 document.querySelector(elem).className+=' first second third

到目前为止,我必须这样做:

elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");
而这在jQuery中是可行的,就像这样

$(elem).addClass("first second third");

我想知道是否有添加或删除类的原生方法。

向元素添加类

document.querySelector(elem).className+=' first second third';
更新:

删除一个类

document.querySelector(elem).className=document.querySelector(elem).className.split(class_to_be_removed).join(" ");

classList
属性确保不会不必要地将重复的类添加到元素中。为了保留此功能,如果您不喜欢正手版本或jQuery版本,我建议添加一个
addMany
函数,并将
removeMany
添加到
DOMTokenList
(类型为
classList
):

更新

elem.classList.remove("first", "second", "third");
根据您的评论,如果您只希望在未定义自定义方法的情况下为这些方法编写自定义方法,请尝试以下操作:

DOMTokenList.prototype.addMany = DOMTokenList.prototype.addMany || function(classes) {...}
DOMTokenList.prototype.removeMany = DOMTokenList.prototype.removeMany || function(classes) {...}

标准定义仅允许添加或删除单个类。几个小包装函数可以满足您的要求:

function addClasses (el, classes) {
  classes = Array.prototype.slice.call (arguments, 1);
  console.log (classes);
  for (var i = classes.length; i--;) {
    classes[i] = classes[i].trim ().split (/\s*,\s*|\s+/);
    for (var j = classes[i].length; j--;)
      el.classList.add (classes[i][j]);
  }
}

function removeClasses (el, classes) {
  classes = Array.prototype.slice.call (arguments, 1);
  for (var i = classes.length; i--;) {
    classes[i] = classes[i].trim ().split (/\s*,\s*|\s+/);
    for (var j = classes[i].length; j--;)
      el.classList.remove (classes[i][j]);
  }
}
这些包装器允许您将类列表指定为单独的参数、带有空格或逗号分隔项的字符串或组合。有关示例,请参见

平等

elem.classList.add("first","second","third");
较新版本的允许使用多个参数
add()
remove()
,以及另一个参数
toggle()
强制状态

在撰写本文时,Chrome支持
add()
remove()
的多个参数,但其他浏览器都不支持。IE 10和更低版本、Firefox 23和更低版本、Chrome 23和更低版本以及其他浏览器不支持
toggle()
的第二个参数

我写了下面的小polyfill来帮助我度过难关,直到支持扩大:

(function () {
    /*global DOMTokenList */
    var dummy  = document.createElement('div'),
        dtp    = DOMTokenList.prototype,
        toggle = dtp.toggle,
        add    = dtp.add,
        rem    = dtp.remove;

    dummy.classList.add('class1', 'class2');

    // Older versions of the HTMLElement.classList spec didn't allow multiple
    // arguments, easy to test for
    if (!dummy.classList.contains('class2')) {
        dtp.add    = function () {
            Array.prototype.forEach.call(arguments, add.bind(this));
        };
        dtp.remove = function () {
            Array.prototype.forEach.call(arguments, rem.bind(this));
        };
    }

    // Older versions of the spec didn't have a forcedState argument for
    // `toggle` either, test by checking the return value after forcing
    if (!dummy.classList.toggle('class1', true)) {
        dtp.toggle = function (cls, forcedState) {
            if (forcedState === undefined)
                return toggle.call(this, cls);

            (forcedState ? add : rem).call(this, cls);
            return !!forcedState;
        };
    }
})();

一个符合ES5标准和
DOMTokenList
的现代浏览器是可以期待的,但我在几个特定的目标环境中使用了这个polyfill,所以它对我来说非常好,但它可能需要调整脚本,以便在IE 8和更低版本的传统浏览器环境中运行。

我喜欢@rich.kelly的答案,但是我想使用与
classList.add()相同的命名法(逗号分隔的字符串),所以有一点偏差

DOMTokenList.prototype.addMany = DOMTokenList.prototype.addMany || function() {
  for (var i = 0; i < arguments.length; i++) {
    this.add(arguments[i]);
  }
}
DOMTokenList.prototype.removeMany = DOMTokenList.prototype.removeMany || function() {
  for (var i = 0; i < arguments.length; i++) {
    this.remove(arguments[i]);
  }
}
我需要测试所有浏览器,但这对Chrome有效。

我们是否应该检查是否存在比
DOMTokenList.prototype.addMany
更具体的东西?究竟是什么原因导致
classList.add()
在IE11中失败?

另一个
元素的polyfill是。我是通过电话找到的

我包含了这个脚本,并使用
元素.classList.add(“第一”、“第二”、“第三”)

由于
classList
中的
add()
方法只允许传递单独的参数,而不是单个数组,因此需要使用apply调用
add()
。对于第一个参数,需要从同一DOM节点传递
classList
引用,作为第二个参数,需要添加的类数组:

element.classList.add.apply(
  element.classList,
  ['class-0', 'class-1', 'class-2']
);
新功能使应用多个CSS类作为数组变得更加容易:

const list = ['first', 'second', 'third'];
element.classList.add(...list);

假设要添加一个类数组,可以使用ES6扩展语法:


让类=['first','second','third'];
元素classList.add(…类);

这是一个针对IE10和IE11用户的解决方案,看起来很简单

var elem=document.getElementById('elem');
['first','second','third'].forEach(item=>elem.classList.add(item))

你好,世界一个非常简单、不花哨但有效的解决方案,我不得不相信它是非常跨浏览器的:

创建此函数

函数removeAddClasses(类列表、removeCollection、addCollection){
对于(var i=0;i你可以像下面这样做

添加

elem.classList.add("first", "second", "third");
删除

elem.classList.remove("first", "second", "third");

TLDR;

在上述简单的情况下,删除应该有效。但在删除的情况下,您应该在删除它们之前确保类存在

const classes = ["first","second","third"];
classes.forEach(c => {
  if (elem.classList.contains(c)) {
     element.classList.remove(c);
  }
})

添加由字符串中的空格分隔的多个类的更好方法是使用:


我找到了一个非常简单的方法,这是一种更现代、更优雅的方法


const el=document.querySelector('.m-element');
//切换
['class1','class2'].map((e)=>el.classList.toggle(e));
//加
['class1','class2'].map((e)=>el.classList.add(e));
//除去
['class1','class2'].map((e)=>el.classList.remove(e));

好的是,您可以轻松地扩展类数组或使用来自API的任何元素。

最佳解决方案之一是检查元素是否存在,然后继续添加或删除,最重要的是,如果元素为空,则删除它

/**
*@description检测obj是否为元素
*@param{*}obj
*@returns{Boolean}
*@example
*见下文
*/
函数isElement(obj){
如果(对象的类型!=“对象”){
返回错误
}
让原型str,原型
做{
prototype=Object.getPrototypeOf(obj)
//在iframe中工作
prototypeStr=Object.prototype.toString.call(prototype)
//“[对象文档]”用于检测文档
如果(
prototypeStr==='[对象元素]'||
prototypeStr==='[对象文档]'
) {
返回真值
}
obj=原型
//null是对象的终端
}while(原型!==null)
返回错误
}
/*
*添加多个类
*addClasses(元素,['class1','class2','class3']))
*el:element | document.querySelector(“.mydiv”);
*类:传递::数组或字符串:[]|“cl1,cl2”|“cl1 cl2”|“cl1 | cl2”
*/
函数addClasses(el,类){
classes=Array.prototype.slice.call(参数,1);
if(isElement(el)){//if(document.body.contains(el)
for(var i=classes.length;i--;){
类[i]=Array.isArray(类[i])?类[i]:类[i].trim().split(/\s*,\s*|\s+/);
对于(var j=类[i]。长度;j-->)
el.classList.add(类[i][j]);
}
}
}
/*
*雷莫
elem.classList.add("first", "second", "third");
elem.classList.remove("first", "second", "third");
const classes = ["first","second","third"];
classes.forEach(c => {
  if (elem.classList.contains(c)) {
     element.classList.remove(c);
  }
})
element.classList.add(...classesStr.split(" "));