ti-enxame.com

Limpar element.classList

element.classList é do tipo DOMTokenList .

Existe um método para limpar esta lista?

35
warvariuc

Não estou ciente de um "método" no sentido de uma "função" associada a classList. Possui os métodos .add() e .remove() para adicionar ou remover classes individuais, mas você pode limpar a lista no sentido de remover todas as classes do elemento como este:

element.className = "";
58
nnnnnn
var classList = element.classList;
while (classList.length > 0) {
   classList.remove(classList.item(0));
}
8
Fredrik_Macrobond

Com o ES6 e o ​​operador spread, isso é fácil.

element.classList.remove(...element.classList);

Isso espalhará os itens da lista como argumentos para o método remove.
Como o método classList.remove pode receber muitos argumentos, todos eles são removidos e o classList é limpo.

Mesmo que seja legível, não é muito eficiente. @Fredrik Macrobond's answer é mais rápido.
Veja as diferentes soluções e os resultados dos testes em jsperf .

4
pekaaw

Eu recomendo não usar className como classList poderia resultar em atualizações mais rápidas do DOM.

O método remove() de DOMTokenList (que é o que classList é) pode receber vários argumentos - cada um uma sequência de um nome de classe a ser removida ( referência ) Primeiro você precisa converter o classList em uma matriz de nomes de classes planejada. Algumas pessoas usam Array.prototype.slice() para fazer isso, mas eu não sou fã e eu pense um loop for é mais rápido na maioria dos navegadores - mas de qualquer forma eu não tenho nada contra loops e a fatia geralmente parecem um hack para mim. Depois de ter a matriz, basta usar apply() para passar essa matriz como uma lista de argumentos.

Eu uso uma classe de utilidade que escrevi para fazer isso. O primeiro método é o que você está procurando, mas estou incluindo um pouco mais para sua referência.

ElementTools.clearClassList = function(elem) {
    var classList = elem.classList;
    var classListAsArray = new Array(classList.length);
    for (var i = 0, len = classList.length; i < len; i++) {
        classListAsArray[i] = classList[i];
    }
    ElementTools.removeClassList(elem, classListAsArray);
}
ElementTools.removeClassList = function(elem, classArray) {
    var classList = elem.classList;
    classList.remove.apply(classList, classArray);
};
ElementTools.addClassList = function(elem, newClassArray) {
    var classList = elem.classList;
    classList.add.apply(classList, newClassArray);
};
ElementTools.setClassList = function(elem, newClassArray) {
    ElementTools.clearClassList(elem);
    ElementTools.addClassList(elem, newClassArray);
};

Observe que eu não o testei completamente em todos os navegadores, pois o projeto em que estou trabalhando só precisa funcionar em um conjunto muito limitado de navegadores modernos. Mas deveria retornará ao IE10 e, se você incluir um calço ( https://github.com/eligrey/classList.js ) para classList, ele = deveria trabalhe de volta para o IE7 (e também com os SVGs, já que o shim de Eli Grey adiciona suporte ao SVG em navegadores não suportados também).

Uma abordagem alternativa que eu considerei era fazer um loop para trás através do classList e chamar remove() no classList para cada entrada. (Para trás, porque o comprimento muda à medida que você remove cada um.) Embora isso também deva funcionar, imaginei que o uso de vários argumentos em remove() poderia ser mais rápido, pois os navegadores modernos podem otimizar isso e evitar várias atualizações no DOM cada vez que chamo remove () em um loop for. Além disso, ambas as abordagens exigem um loop for (para criar uma lista ou remover cada uma), por isso não vi benefícios nessa abordagem alternativa. Mas, novamente, eu fiz não fiz testes de velocidade.

Se alguém testar a velocidade das várias abordagens ou tiver uma solução melhor, poste.

[~ # ~] edit [~ # ~] : Encontrei um bug no calço que impede a adição correta de suporte ao IE11/10 para vários argumentos para add() e remove(). Eu arquivei um relatório no github.

1
Michael - Plaudit Design