O que é a função "hasClass" com JavaScript simples?

313

Como você faz jQuery hasClasscom JavaScript simples? Por exemplo,

<body class="foo thatClass bar">

Qual é a maneira do JavaScript de perguntar se <body>existe thatClass?

Kyle
fonte
Suponho que você precisaria analisar a classpropriedade (que no caso de várias classes terá vários nomes de classes em ordem aleatória, separados por um espaço) e verificar se o nome da sua classe está nela. Não terrivelmente difícil, mas ainda terrivelmente inconveniente, se não para fins de aprendizagem :)
Pekka
7
Não sei se estou atrasado para a festa, mas um bom site que dá alternativas para funções jQuery é youmightnotneedjquery.com
Ithil

Respostas:

116

Você pode verificar se element.classNamecorresponde /\bthatClass\b/.
\bcorresponde a uma quebra de palavra.

Ou, você pode usar a própria implementação do jQuery:

var className = " " + selector + " ";
if ( (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(" thatClass ") > -1 ) 

Para responder sua pergunta mais geral, você pode consultar o código-fonte do jQuery no github ou na fonte, hasClassespecificamente neste visualizador de código-fonte .

SLaks
fonte
6
+1 para implementação do jQuery (de por ter consultado (isso é inglês?) O que rclassrealmente é;))
Felix Kling
6
Não \bcorresponderia a "thatClass-anotherClass"?
Matthew Crumley 23/02
3
apenas para ser completo: rclass nas versões recentes é "/ [\ n \ t \ r] / g" (\ r adicionado)
Felix Schwarz
4
@FelixSchwarz está certo, no jQuery atual o regexp foi atualizado para /[\t\r\n\f]/g. Também é bom mencionar que /\bclass\b/pode falhar para nomes de classes com -sinal de menos (exceto que funcione bem), é por isso que a implementação do jQuery é melhor e mais confiável. Por exemplo: /\bbig\b/.test('big-text')retorna verdadeiro em vez de falso esperado.
Stano 18/06
996

Basta usar classList.contains():

if (document.body.classList.contains('thatClass')) {
    // do some stuff
}

Outros usos de classList:

document.body.classList.add('thisClass');
// $('body').addClass('thisClass');

document.body.classList.remove('thatClass');
// $('body').removeClass('thatClass');

document.body.classList.toggle('anotherClass');
// $('body').toggleClass('anotherClass');

Suporte do navegador:

  • Chrome 8.0
  • Firefox 3.6
  • IE 10
  • Opera 11.50
  • Safari 5.1

classList Suporte do navegador

Damien
fonte
5
Isso não é suportado no IE8 . IE8 pode recuperar .classListcomo uma string, mas não vai reconhecer os métodos mais modernos, tais como.classList.contains()
iono
7
@iono Na descrição da implementação Element.classList do MDN, há um calço que estende o suporte a esse comportamento para o IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
James
3
Concordo com @AlexanderWigmore, isso foi incrivelmente útil e simples.
Jacques Olivier
Votos isso. Esta é uma maneira muito mais limpa de consultar as classes
user2190488 28/03/19
@ Slaks, isso deve ser atualizado para ser a resposta aceita já.
Umur Karagöz
35

O forro mais eficaz que

  • retorna um booleano (ao contrário da resposta de Orbling)
  • Não retorna um falso positivo ao procurar thisClassem um elemento que possui class="thisClass-suffix".
  • é compatível com todos os navegadores até pelo menos IE6

function hasClass( target, className ) {
    return new RegExp('(\\s|^)' + className + '(\\s|$)').test(target.className);
}
Raveren
fonte
28

O atributo que armazena as classes em uso é className.

Então você pode dizer:

if (document.body.className.match(/\bmyclass\b/)) {
    ....
}

Se você deseja um local que mostre como o jQuery faz tudo, sugiro:

http://code.jquery.com/jquery-1.5.js

Orbling
fonte
1
Excelente. O matchatributo é útil novamente! Realmente jQuery faz algo mais do que é possível em JavaScript ?! Caso contrário, o jQuery é apenas um peso desnecessário de taquigrafia.
animaacija 4/01/15
1
Isso também corresponde myclass-something, como \bcorresponde ao hífen.
Marc Durdin
1
@animaacija Todas as bibliotecas / plug-ins javascript são basicamente atalhos de javascript porque são construídos com javascript. A coisa é: taquigrafia são sempre necessárias. Nunca reinvente a roda.
Edwin Stoteler
Esta é uma otima soluçao!
Manuel Abascal
28

// 1. Use if for see that classes:

if (document.querySelector(".section-name").classList.contains("section-filter")) {
  alert("Grid section");
  // code...
}
<!--2. Add a class in the .html:-->

<div class="section-name section-filter">...</div>

StiveAZ
fonte
4
@greg_diesel: não desencoraje respostas! Novas soluções para problemas comuns são mais que bem-vindas.
raveren
2
@ Raveren, enquanto novas soluções para problemas antigos são bem-vindas, essa resposta em particular não traz novidades. Isso apenas adiciona ruído a essa pergunta.
Emile Bergeron
1
@raveren Esta não é uma solução nova, é a mesma que esta resposta, mas com menos informações.
Fund Monica's Lawsuit
13

Função hasClass:

HTMLElement.prototype.hasClass = function(cls) {
    var i;
    var classes = this.className.split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] == cls) {
            return true;
        }
    }
    return false;
};

Função addClass:

HTMLElement.prototype.addClass = function(add) {
    if (!this.hasClass(add)){
        this.className = (this.className + " " + add).trim();
    }
};

função removeClass:

HTMLElement.prototype.removeClass = function(remove) {
    var newClassName = "";
    var i;
    var classes = this.className.replace(/\s{2,}/g, ' ').split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] !== remove) {
            newClassName += classes[i] + " ";
        }
    }
    this.className = newClassName.trim();
};
Gawin
fonte
11

Eu uso uma solução simples / mínima, uma linha, entre navegadores e também funciona com navegadores herdados:

/\bmyClass/.test(document.body.className) // notice the \b command for whole word 'myClass'

Esse método é ótimo porque não requer polyfills e, se você usá-los classList, é muito melhor em termos de desempenho. Pelo menos para mim.

Atualização: criei um pequeno polyfill que é uma solução completa que uso agora:

function hasClass(element,testClass){
  if ('classList' in element) { return element.classList.contains(testClass);
} else { return new Regexp(testClass).exec(element.className); } // this is better

//} else { return el.className.indexOf(testClass) != -1; } // this is faster but requires indexOf() polyfill
  return false;
}

Para a outra manipulação de classe, veja o arquivo completo aqui .

thednp
fonte
2
Será que esta viagem sobre uma classe de notmyClassHere?
Teepeemm
2
Você também pode perguntar se sua turma não está presente, bem como !/myClass/.test(document.body.className)observar o !símbolo.
Thednp 04/10/2015
1
Não estou falando de negar a pergunta. Estou pensando que sua função retornará incorretamente true se o nome da classe for thisIsmyClassHere.
4134 Teepeemm
1
Eu estava supondo que é isso que você pergunta, não entendeu exatamente o que você precisa, mas você já tentou e não conseguiu retornar verdadeiro / falso como deveria?
Thednp
2
Isso não é perfeito, pois não é à prova de substrings. Por exemplo, quando document.body.className = 'myClass123', então /myClass/.test(document.body.className) return true ...
Zbigniew Wiadro
9

Uma boa solução para isso é trabalhar com classList e contains.

eu fiz assim:

... for ( var i = 0; i < container.length; i++ ) {
        if ( container[i].classList.contains('half_width') ) { ...

Então você precisa do seu elemento e verifique a lista de classes. Se uma das classes for a mesma que você procura, ela retornará true, caso contrário, retornará false!

Bastian Fießinger
fonte
6

Use algo como:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');
Alejandro Nanez
fonte
3
Isso não é equivalente a myHTMLSelector.classList.indexOf('the-class')? Você também não quer >=0no final?
Teepeemm
5
Qual é o sentido de usar [].indexOfse classListtem um containsmétodo?
Oriol
@Teepeemm no. myHTMLSelector.classList.indexOf('the-class')retorna o erro que, myHTMLSelector.classList.indexOf is not a functionporque myHTMLSelector.classListnão é uma matriz. Mas acho que ao chamá-lo usando Array.prototypealguma conversão acontece. Isso pode suportar navegadores mais antigos, embora containstenha um suporte muito bom.
Ehsan88 6/03
4
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}
Alexandr Karbivnichiy
fonte
2

Essa função 'hasClass' funciona no IE8 +, FireFox e Chrome:

hasClass = function(el, cls) {
    var regexp = new RegExp('(\\s|^)' + cls + '(\\s|$)'),
        target = (typeof el.className === 'undefined') ? window.event.srcElement : el;
    return target.className.match(regexp);
}
manufosela
fonte
1

Bem, todas as respostas acima são muito boas, mas aqui está uma pequena função simples que eu criei. Funciona muito bem.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}
j0hnstew
fonte
3
Qual é o objetivo de iterar se classListtem um containsmétodo?
Oriol
1

O que você acha dessa abordagem?

<body class="thatClass anotherClass"> </body>

var bodyClasses = document.querySelector('body').className;
var myClass = new RegExp("thatClass");
var trueOrFalse = myClass.test( bodyClasses );

https://jsfiddle.net/5sv30bhe/

Marian07
fonte
2
Eu acho que você está misturando seus nomes de variáveis ​​(ativo === myClass?). Mas essa abordagem não dará um falso positivo class="nothatClassIsnt"?
Teepeemm
0

Aqui está a maneira mais simples:

var allElements = document.querySelectorAll('*');
for (var i = 0; i < allElements.length; i++) {
    if (allElements[i].hasAttribute("class")) {
         //console.log(allElements[i].className);
         if (allElements[i].className.includes("_the _class ")) { 
              console.log("I see the class");
         }
    }
}
Comunidade Ans
fonte