Co to jest funkcja „hasClass” ze zwykłym JavaScriptem?


313

Jak robisz jQuery za hasClasspomocą zwykłego JavaScript? Na przykład,

<body class="foo thatClass bar">

W jaki sposób JavaScript pyta, czy <body>ma thatClass?


Przypuszczam, że musiałbyś przeanalizować classwłaściwość (która w przypadku wielu klas będzie miała wiele nazw klas w losowej kolejności oddzielonych spacją) i sprawdzisz, czy w nich jest nazwa twojej klasy. Nie strasznie trudne, ale wciąż okropnie niewygodne, jeśli nie do celów edukacyjnych :)
Pekka

7
nie wiem, czy jestem spóźniony na imprezę, ale dobrą stroną, która daje alternatywy dla funkcji jQuery, jest youmightnotneedjquery.com
ithil

Odpowiedzi:


116

Możesz sprawdzić, czy element.classNamepasuje /\bthatClass\b/.
\bpasuje do podziału słowa.

Lub możesz użyć własnej implementacji jQuery:

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

Aby odpowiedzieć na bardziej ogólne pytanie, możesz spojrzeć na kod źródłowy jQuery na github lub na źródło dla hasClasskonkretnie w tej przeglądarce źródła .


6
+1 za implementację jQuery (za to, że sprawdził (czy to jest poprawny angielski?), Co rclasstak naprawdę jest;))
Felix Kling

6
Nie \bpasowałbyś do „thatClass-anotherClass”?
Matthew Crumley

3
dla kompletności: rclass w najnowszych wersjach to „/ [\ n \ t \ r] / g” (\ r dodano)
Felix Schwarz

4
@ FelixSchwarz ma rację, w bieżącym jQuery wyrażenie regularne zostało zaktualizowane do /[\t\r\n\f]/g. Warto również wspomnieć, że /\bclass\b/może się nie powieść dla nazw klas ze -znakiem minus (poza tym, że działa dobrze), dlatego implementacja jQuery jest lepsza i bardziej niezawodna. Na przykład: /\bbig\b/.test('big-text')zwraca true zamiast oczekiwanego false.
Stano

994

Po prostu użyj classList.contains():

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

Inne zastosowania 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');

Obsługa przeglądarki:

  • Chrome 8.0
  • Firefox 3.6
  • IE 10
  • Opera 11,50
  • Safari 5.1

classList Obsługa przeglądarki


5
To nie jest obsługiwane w IE8 . IE8 może pobierać .classListjako ciąg znaków, ale nie rozpoznaje nowocześniejszych metod, takich jak.classList.contains()
iono

7
@iono W opisie implementacji Element.classList z MDN znajduje się podkładka, która rozszerza obsługę tego zachowania na IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
James

3
Zgadzam się z @AlexanderWigmore, było to niezwykle pomocne i proste.
Jacques Olivier,

Głosuje na to. Jest to znacznie
prostszy

@SLaks powinno to zostać zaktualizowane, aby było już akceptowaną odpowiedzią.
Umur Karagöz

35

Najbardziej skuteczna jedna podszewka

  • zwraca wartość logiczną (w przeciwieństwie do odpowiedzi Orblinga)
  • Nie zwraca fałszywie dodatniego wyniku wyszukiwania thisClasselementu, który ma class="thisClass-suffix".
  • jest kompatybilny z każdą przeglądarką do co najmniej IE6

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

28

Atrybut przechowujący używane klasy to className.

Możesz więc powiedzieć:

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

Jeśli potrzebujesz lokalizacji, która pokazuje, jak jQuery robi wszystko, sugerowałbym:

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


1
Świetny. matchAtrybut jest przydatny ponownie! Czy naprawdę jQuery robi coś więcej niż jest możliwe w JavaScript ?! Jeśli nie, jQuery to po prostu niepotrzebna waga skrótów.
animaacija

1
To również pasuje myclass-something, podobnie jak \błącznik.
Marc Durdin

1
@animaacija Wszystkie biblioteki / wtyczki javascript są w skrócie javascript, ponieważ są budowane przy użyciu javascript. Rzecz w tym: Stenografia jest zawsze konieczna. Nigdy nie wymyślaj koła na nowo.
Edwin Stoteler,

To świetne rozwiązanie!
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: nie zniechęcaj do odpowiedzi! Nowe rozwiązania typowych problemów są mile widziane.
raveren

2
@Raveren, choć mile widziane są nowe rozwiązania starych problemów, ta konkretna odpowiedź nie wnosi nic nowego. To tylko dodaje hałasu do tego pytania.
Emile Bergeron,

1
@raveren To nie jest nowe rozwiązanie, to ta sama odpowiedź, ale z mniejszą ilością informacji.
Pozew Fund Moniki w

13

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

funkcja addClass:

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

funkcja 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

Korzystam z prostego / minimalnego rozwiązania, jednej linii, w różnych przeglądarkach, a także współpracuję ze starszymi przeglądarkami:

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

Ta metoda jest świetna, ponieważ nie wymaga wypełniania wieloskładnikowego i jeśli go używaszclassList , jest znacznie lepsza pod względem wydajności. Przynajmniej dla mnie.

Aktualizacja: Zrobiłem malutkie wypełnienie, które jest teraz wszechstronnym rozwiązaniem:

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

W przypadku innych manipulacji klasami zobacz pełny plik tutaj .


2
Czy ta podróż nad klasą notmyClassHere?
Teepeemm

2
Możesz również zapytać, czy nie ma tam twojej klasy, !/myClass/.test(document.body.className)zauważ także ten !symbol.
thednp

1
Nie mówię o negowaniu pytania. Myślę, że twoja funkcja niepoprawnie zwróci true, jeśli nazwa klasy to thisIsmyClassHere.
Teepeemm,

1
Tylko zgadywałam, że o to pytasz, nie rozumiałam dokładnie, czego potrzebujesz, ale czy próbowałeś tego i nie powrócił prawda / fałsz, jak powinien?
thednp

2
Nie jest to idealne, ponieważ nie jest odporne na podciągi. Np. Kiedy document.body.className = 'myClass123', wtedy /myClass/.test(document.body.className) zwraca true ...
Zbigniew Wiadro

9

dobrym rozwiązaniem jest praca z classList i zawiera.

zrobiłem to tak:

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

Potrzebujesz więc swojego elementu i sprawdź listę klas. Jeśli jedna z klas jest taka sama jak ta, której szukasz, zwróci true, jeśli nie, zwróci false!


6

Użyj czegoś takiego:

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

3
Czy to nie jest równoważne z myHTMLSelector.classList.indexOf('the-class')? Nie chcesz też >=0na końcu?
Teepeemm

5
Jaki jest sens używania, [].indexOfjeśli classListma containsmetodę?
Oriol

@Teepeemm no. myHTMLSelector.classList.indexOf('the-class')zwraca błąd, który myHTMLSelector.classList.indexOf is not a functionponieważ myHTMLSelector.classListnie jest tablicą. Ale myślę, że nazywając to za pomocą Array.prototypekonwersji, zdarza się. Może to obsługiwać starszą przeglądarkę, ale containsma bardzo dobre wsparcie.
Ehsan88


2

Ta funkcja „hasClass” działa w IE8 +, FireFox i 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

Cóż, wszystkie powyższe odpowiedzi są całkiem dobre, ale oto mała prosta funkcja, którą podniosłem. Działa całkiem dobrze.

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

3
Jaki jest sens iteracji, jeśli classListma containsmetodę?
Oriol,

1

Co sądzisz o tym podejściu?

<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
Myślę, że miksujesz nazwy zmiennych (aktywne === myClass?). Ale czy to podejście nie daje fałszywie pozytywnego wyniku class="nothatClassIsnt"?
Teepeemm

0

Oto najprostszy sposób:

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");
         }
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.