Verifique se a classe já foi atribuída antes de adicionar

113

Em jQuery, é recomendado verificar se uma classe já está atribuída a um elemento antes de adicionar essa classe? Será que vai ter algum efeito?

Por exemplo:

<label class='foo'>bar</label>

Em caso de dúvida se a classe bazjá foi atribuída label, esta seria a melhor abordagem:

var class = 'baz';
if (!$('label').hasClass(class)) {
  $('label').addClass(class);
}

ou isso seria o suficiente:

$('label').addClass('baz');
Muleskinner
fonte
12
Usei .hasClassapenas quando preciso verificar se existe aula, se só preciso atribuir aula - eu uso .addClass. jQuery não duplica as classes
Samich
7
Basta adicionar a classe sem testar. Se já existir, não será adicionado novamente.
Blazemonger

Respostas:

177

Basta ligar addClass(). jQuery fará a verificação para você. Se você verificar por conta própria, estará duplicando o trabalho, pois o jQuery ainda executará a verificação para você.

jmar777
fonte
47

Uma simples verificação no console diria que ligar addClassvárias vezes com a mesma classe é seguro.

Especificamente, você pode encontrar o cheque na fonte

if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
  setClass += classNames[ c ] + " ";
}
Raynos
fonte
2
Por favor, releia minha pergunta e você notará que não é sobre ser seguro, mas sobre as melhores práticas
Muleskinner
7
Pela sua resposta editada, vejo que o jQuery realmente verifica se a classe já está atribuída antes de adicioná-la, ou seja, seria uma má prática verificar você mesmo / obrigado
Muleskinner
5
@Muleskinner é o que eu queria dizer.
Raynos
41
@Raynos: Uma simples verificação no console diria que é seguro chamar addClass várias vezes com a mesma classe. Ainda assim, essa pergunta foi um dos maiores sucessos quando eu pesquisei uma resposta no Google ... Mesmo coisas triviais que estão bem documentadas em outro lugar têm lugar no Stack Overflow.
eirirlar
10
Há muita atitude nesta resposta. Poderia ter respondido com algum tato.
dreadwail de
4

Esta questão chamou minha atenção após outra que foi marcada como uma duplicata desta .

Esta resposta resume a resposta aceita com alguns detalhes adicionais.

Você está tentando otimizar evitando uma verificação desnecessária; a esse respeito, aqui estão alguns fatores que você deve estar ciente:

  1. não é possível ter nomes de classe duplicados no atributo de classe por meio da manipulação de um elemento DOM via JavaScript. Se você tiver class="collapse"em seu HTML, a chamada Element.classList.add("collapse");não adicionará uma classe de recolhimento adicional . Não sei a implementação subjacente, mas acho que deve ser boa o suficiente.
  2. JQuery faz algumas verificações necessárias em seus addClasse removeClassimplementações (eu verifiquei o código fonte ). Pois addClass, depois de fazer algumas verificações e se existir uma classe, o JQuery não tenta adicioná-la novamente. Da mesma forma para removeClass, JQuery faz algo ao longo da linha cur.replace( " " + clazz + " ", " " );que removerá uma classe apenas se ela existir.

Vale a pena notar, JQuery faz alguma otimização em sua removeClassimplementação para evitar uma nova renderização sem sentido. É assim

...
// only assign if different to avoid unneeded rendering.
finalValue = value ? jQuery.trim( cur ) : "";
if ( elem.className !== finalValue ) {
    elem.className = finalValue;
}
...

Portanto, a melhor micro otimização que você poderia fazer seria com o objetivo de evitar sobrecargas de chamada de função e as verificações de implementação associadas.

Digamos que você queira alternar uma classe chamada collapse, se você está totalmente no controle de quando a classe é adicionada ou removida, e se a collapseclasse está ausente inicialmente, então você pode otimizar da seguinte forma:

$(document).on("scroll", (function () {
    // hold state with this field
    var collapsed = false;

    return function () {
        var scrollTop, shouldCollapse;

        scrollTop = $(this).scrollTop();
        shouldCollapse = scrollTop > 50;

        if (shouldCollapse && !collapsed) {
            $("nav .branding").addClass("collapse");
            collapsed = true;

            return;
        }

        if (!shouldCollapse && collapsed) {
            $("nav .branding").removeClass("collapse");
            collapsed = false;
        }
    };
})());

Como um aparte, se você estiver alternando uma classe devido a mudanças na posição de rolagem, é altamente recomendável acelerar o tratamento de evento de rolagem.

Igwe Kalu
fonte
1
$("label")
  .not(".foo")
  .addClass("foo");
טאבו ישראל שרות לקוחות
fonte