Есть ли способ добавить/удалить несколько классов в одной команде с classList?

До сих пор я должен это делать:

elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");

Пока это возможно в jQuery, например

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

Я хотел бы знать, есть ли какой-либо родной способ добавления или удаления.

Ответ 1

elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");

равно

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

Ответ 2

Новый оператор упрощает применение нескольких классов CSS в качестве массива:

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

Ответ 3

Свойство classList гарантирует, что дублирующие классы не будут излишне добавлены к элементу. Чтобы сохранить эту функциональность, если вам не нравятся версии longhand или версия jQuery, я бы предложил добавить функцию addMany и removeMany в DOMTokenList (тип classList):

DOMTokenList.prototype.addMany = function(classes) {
    var array = classes.split(' ');
    for (var i = 0, length = array.length; i < length; i++) {
      this.add(array[i]);
    }
}

DOMTokenList.prototype.removeMany = function(classes) {
    var array = classes.split(' ');
    for (var i = 0, length = array.length; i < length; i++) {
      this.remove(array[i]);
    }
}

Затем они будут использоваться следующим образом:

elem.classList.addMany("first second third");
elem.classList.removeMany("first third");

Обновление

В соответствии с вашими комментариями, если вы хотите написать собственный метод для них, если они не определены, попробуйте выполнить следующее:

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

Ответ 4

Так как метод add() из classList просто позволяет передавать отдельные аргументы, а не один массив, вам нужно выставить add() с помощью apply. Для первого аргумента вам нужно передать ссылку classList из того же DOM node, а в качестве второго аргумента - массив классов, который вы хотите добавить:

element.classList.add.apply(
  element.classList,
  ['class-0', 'class-1', 'class-2']
);

Ответ 5

Более новые версии Спецификация DOMTokenList позволяют использовать несколько аргументов 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 и ниже.

Ответ 6

Чтобы добавить класс к элементу

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

UPDATE:

Удалить класс

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

Ответ 7

Стандартное определение позволяет только добавлять или удалять один класс. Несколько мелких функций обертки могут делать то, что вы просите:

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]);
  }
}

Эти обертки позволяют вам указать список классов как отдельные аргументы, как строки с пробелом или запятыми, или комбинацию. Для примера см. http://jsfiddle.net/jstoolsmith/eCqy7

Ответ 8

Вот работа для пользователей IE 10 и 11, которые выглядели довольно прямо.

var elem = document.getElementById('elem');

['first','second','third'].map(item => elem.classList.add(item));
<div id="elem">Hello World!</div>

Ответ 9

Мне понравился @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]);
  }
}

Итак, вы можете использовать:

document.body.classList.addMany('class-one','class-two','class-three');

Мне нужно протестировать все браузеры, но это сработало для Chrome.
 Должны ли мы проверять что-то более конкретное, чем существование DOMTokenList.prototype.addMany? Что именно вызывает отказ classList.add() в IE11?

Ответ 10

Другим polyfill для element.classList является здесь. Я нашел его через MDN.

Я включаю в себя script и использую element.classList.add("first","second","third"), как и предполагалось.

Ответ 11

Предположим, что у вас есть набор добавляемых классов, вы можете использовать синтаксис распространения ES6:

let classes = ['first', 'second', 'third']; elem.classList.add(...classes);