Che cos'è la funzione "hasClass" con JavaScript semplice?


313

Come si fa jQuery hasClasscon JavaScript semplice? Per esempio,

<body class="foo thatClass bar">

Qual è il modo JavaScript per chiedere se <body>ha thatClass?


Suppongo che dovresti analizzare la classproprietà (che in caso di più classi avrà più nomi di classe in ordine casuale separati da uno spazio) e verificare se il nome della tua classe è presente. Non tremendamente difficile, ma comunque terribilmente scomodo se non per scopi di apprendimento :)
Pekka,

7
non so se sono in ritardo per la festa, ma un buon sito che offre alternative alle funzioni di jQuery è youmightnotneedjquery.com
entro il

Risposte:


116

Puoi controllare se le element.classNamepartite /\bthatClass\b/.
\bcorrisponde a una pausa di parole.

In alternativa, è possibile utilizzare l'implementazione di jQuery:

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

Per rispondere alla tua domanda più generale, puoi guardare il codice sorgente di jQuery su github o l'origine per questo hasClassspecifico visualizzatore di sorgenti .


6
+1 per l'implementazione di jQuery (di aver cercato (è proprio questo l'inglese?) Che cosa rclassè in realtà;))
Felix Kling

6
Non \bcorrisponderebbe a "thatClass-anotherClass"?
Matthew Crumley,

3
solo per completezza: rclass nelle ultime versioni è "/ [\ n \ t \ r] / g" (\ r aggiunto)
Felix Schwarz,

4
@FelixSchwarz ha ragione, nell'attuale jQuery è stato aggiornato regexp /[\t\r\n\f]/g. Inoltre è bene ricordare che /\bclass\b/per i nomi di classe con -segno meno (a parte quello che funziona bene) può fallire , ecco perché l'implementazione di jQuery è migliore e più affidabile. Ad esempio: /\bbig\b/.test('big-text')restituisce true anziché false previsto.
Stano,

996

Usa semplicemente classList.contains():

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

Altri usi di 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');

Supporto browser:

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

classList Supporto per il browser


5
Questo non è supportato in IE8 . IE8 può recuperare .classListcome stringa, ma non riconoscerà i metodi più moderni come.classList.contains()
iono

7
@iono Nella descrizione dell'implementazione di Element.classList dall'MDN c'è uno spessore che estende il supporto a questo comportamento a IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
James

3
Sono d'accordo con @AlexanderWigmore, questo è stato incredibilmente utile e semplice.
Jacques Olivier,

Vota questo. Questo è un modo molto più semplice di interrogare le classi
user2190488

@SLaks questo dovrebbe essere aggiornato per essere già la risposta accettata.
Umur Karagöz,

35

Quello più efficace è quello

  • restituisce un valore booleano (al contrario della risposta di Orbling)
  • Non restituisce un falso positivo durante la ricerca di thisClassun elemento che ha class="thisClass-suffix".
  • è compatibile con tutti i browser fino ad almeno IE6

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

28

L'attributo che memorizza le classi in uso è className.

Quindi puoi dire:

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

Se vuoi una posizione che ti mostri come jQuery fa tutto, ti suggerirei:

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


1
Eccellente. L' matchattributo torna utile! JQuery fa davvero qualcosa di più di quanto sia possibile in JavaScript ?! Altrimenti, jQuery è solo un peso inutile di shorthands.
animaacija,

1
Anche questo corrisponde myclass-something, come \bcorrisponde al trattino.
Marc Durdin,

1
@animaacija Tutte le librerie / plugin javascript sono fondamentalmente delle scorciatoie javascript perché sono costruite con javascript. La cosa è: gli shorthands sono sempre necessari. Non reinventare mai la ruota.
Edwin Stoteler,

Questa è un'ottima soluzione!
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>


4
@greg_diesel: non scoraggiare le risposte! Nuove soluzioni per problemi comuni sono più che benvenute.
Raveren,

2
@Raveren mentre sono benvenute nuove soluzioni a vecchi problemi, questa particolare risposta non porta nulla di nuovo. Aggiunge solo rumore a questa domanda.
Emile Bergeron,

1
@raveren Questa non è una nuova soluzione, è la stessa di questa risposta ma con meno informazioni.
Fondi Monica's Lawsuit

13

Funzione 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;
};

funzione addClass:

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

funzione 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();
};

11

Uso una soluzione semplice / minima, una riga, cross-browser e funziona anche con i browser legacy:

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

Questo metodo è ottimo perché non richiede i polyfill e se li usi per classListessere molto meglio in termini di prestazioni. Almeno per me.

Aggiornamento: ho creato un piccolo polyfill che è una soluzione a tutto tondo che uso ora:

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

Per la manipolazione dell'altra classe, vedere qui il file completo .


2
Questo viaggio supererà una classe di notmyClassHere?
Teepeemm,

2
Puoi anche chiedere se la tua classe non è presente e !/myClass/.test(document.body.className)notare il !simbolo.
thednp

1
Non sto parlando di negare la domanda. Sto pensando che la tua funzione restituirà erroneamente true se il nome della classe è thisIsmyClassHere.
Teepeemm,

1
Stavo solo indovinando che è quello che chiedi, non hai capito esattamente di cosa hai bisogno, ma l'hai provato e non è riuscito a restituire vero / falso come dovrebbe?
thednp

2
Questo non è perfetto in quanto non è a prova di sottostringhe. Ad esempio quando document.body.className = 'myClass123', quindi /myClass/.test(document.body.className) restituisce true ...
Zbigniew Wiadro

9

una buona soluzione per questo è lavorare con classList e contiene.

l'ho fatto così:

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

Quindi hai bisogno del tuo elemento e controlla l'elenco delle classi. Se una delle classi è uguale a quella che cerchi, restituirà true, altrimenti restituirà false!


6

Usa qualcosa come:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');

3
Non è equivalente a myHTMLSelector.classList.indexOf('the-class')? Non vuoi anche >=0alla fine?
Teepeemm,

5
Che senso ha usare [].indexOfse classListha un containsmetodo?
Oriol,

@Teepeemm no. myHTMLSelector.classList.indexOf('the-class')restituisce l'errore myHTMLSelector.classList.indexOf is not a functionperché poiché myHTMLSelector.classListnon è un array. Ma immagino che quando lo si chiama usando Array.prototypeuna conversione avvenga. Questo può supportare un browser meno recente, sebbene containsabbia un ottimo supporto.
Ehsan88,


2

Questa funzione 'hasClass' funziona in 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);
}

1

Bene, tutte le risposte di cui sopra sono piuttosto buone, ma ecco una piccola funzione che ho montato. Funziona abbastanza bene.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}

3
Che senso ha iterare se classListha un containsmetodo?
Oriol,

1

Cosa ne pensi di questo approccio?

<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/


2
Penso che stai mescolando i nomi delle tue variabili (attivo === myClass?). Ma questo approccio non darà un falso positivo per class="nothatClassIsnt"?
Teepeemm,

0

Ecco il modo più semplice:

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");
         }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.