Pytanie Zmień klasę elementu za pomocą JavaScript


Jak mogę zmienić klasę elementu HTML w odpowiedzi na onClick wydarzenie przy użyciu JavaScript?


2290
2017-10-12 20:06


pochodzenie


"Atrybut class jest najczęściej używany do wskazywania klasy w arkuszu stylów, ale może być również wykorzystany przez JavaScript (przez DOM HTML) do wprowadzania zmian w elementach HTML z określoną klasą." -w3schools.com/tags/att_standard_class.asp - Triynko
element.setAttribute(name, value);  Zastąpić name z class. Zastąpić value bez względu na to, jakie imię podałeś klasie, zawarte w cudzysłowie. Dzięki temu nie trzeba usuwać bieżącej klasy i dodawać innej. To Przykład jsFiddle pokazuje pełny działający kod. - Sandy Good
Aby zmienić klasę elementu HTML za pomocą onClick użyj tego kodu: <input type='button' onclick='addNewClass(this)' value='Create' />   oraz w sekcji javascript: function addNewClass(elem){ elem.className="newClass"; } online - Iman Bahrampour


Odpowiedzi:


Nowoczesne techniki HTML5 do zmiany klas

Dodano nowoczesne przeglądarki classList która zapewnia metody ułatwiające manipulowanie klasami bez potrzeby korzystania z biblioteki:

document.getElementById("MyElement").classList.add('MyClass');

document.getElementById("MyElement").classList.remove('MyClass');

if ( document.getElementById("MyElement").classList.contains('MyClass') )

document.getElementById("MyElement").classList.toggle('MyClass');

Niestety, nie działają one w Internet Explorerze przed wersją 10, chociaż istnieje shim aby dodać obsługę do IE8 i IE9, dostępne od ta strona. Jest coraz więcej utrzymany.

Proste rozwiązanie dla różnych przeglądarek

Używana jest standardowa metoda JavaScript do wybrania elementu document.getElementById("Id"), których używają poniższe przykłady - można oczywiście uzyskać elementy w inny sposób, a we właściwej sytuacji po prostu użyć this zamiast tego - wchodzenie w szczegóły na ten temat wykracza poza zakres odpowiedzi.

Aby zmienić wszystkie klasy dla elementu:

Aby zastąpić wszystkie istniejące klasy jedną lub większą liczbą nowych klas, ustaw atrybut className:

document.getElementById("MyElement").className = "MyClass";

(Aby zastosować wiele klas, możesz użyć listy rozdzielanej spacjami.)

Aby dodać dodatkową klasę do elementu:

Aby dodać klasę do elementu, bez usuwania / zmiany istniejących wartości, dodaj spację i nową nazwę klasy, tak jak poniżej:

document.getElementById("MyElement").className += " MyClass";

Aby usunąć klasę z elementu:

Aby usunąć pojedynczą klasę do elementu, bez wpływu na inne klasy potencjału, wymagana jest prosta zamiana wyrażenia regularnego:

document.getElementById("MyElement").className =
   document.getElementById("MyElement").className.replace
      ( /(?:^|\s)MyClass(?!\S)/g , '' )
/* Code wrapped for readability - above is all one statement */

Wyjaśnienie tego regex jest następujące:

(?:^|\s) # Match the start of the string, or any single whitespace character

MyClass  # The literal text for the classname to remove

(?!\S)   # Negative lookahead to verify the above is the whole classname
         # Ensures there is no non-space character following
         # (i.e. must be end of string or a space)

The g flaga mówi, aby zastąpić, aby powtórzyć w razie potrzeby, na wypadek gdyby nazwa klasy została dodana wiele razy.

Aby sprawdzić, czy klasa jest już zastosowana do elementu:

To samo wyrażenie regularne użyte powyżej do usunięcia klasy może być również użyte do sprawdzenia, czy dana klasa istnieje:

if ( document.getElementById("MyElement").className.match(/(?:^|\s)MyClass(?!\S)/) )


Przypisywanie tych działań do zdarzeń onclick:

Podczas gdy możliwe jest pisanie JavaScript bezpośrednio w atrybutach zdarzeń HTML (takich jak onclick="this.className+=' MyClass'") nie jest to zalecane zachowanie. Zwłaszcza w przypadku większych aplikacji, łatwiejszy do utrzymania kod zostaje osiągnięty poprzez oddzielenie znaczników HTML od logiki interakcji JavaScript.

Pierwszym krokiem do osiągnięcia tego jest utworzenie funkcji i wywołanie funkcji w atrybucie onclick, na przykład:

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }
</script>
...
<button onclick="changeClass()">My Button</button>

(Nie jest wymagane posiadanie tego kodu w znacznikach skryptu, jest to po prostu dla zwięzłości przykładu, a włączenie JavaScriptu do odrębnego pliku może być bardziej odpowiednie).

Drugim krokiem jest przeniesienie zdarzenia onclick z HTML i do JavaScript, na przykład za pomocą addEventListener

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }

    window.onload = function(){
        document.getElementById("MyElement").addEventListener( 'click', changeClass);
    }
</script>
...
<button id="MyElement">My Button</button>

(Zauważ, że część window.onload jest wymagana, aby zawartość tej funkcji była wykonywana po HTML zakończył ładowanie - bez tego MyElement może nie istnieć po wywołaniu kodu JavaScript, więc linia nie powiedzie się.)


JavaScript Frameworks i Biblioteki

Powyższy kod jest w standardowym kodzie JavaScript, jednak powszechną praktyką jest używanie frameworka lub biblioteki do upraszczania typowych zadań, a także czerpania korzyści z naprawionych błędów i skrajnych przypadków, o których możesz nie myśleć podczas pisania kodu.

Podczas gdy niektórzy ludzie uważają, że dodanie ramek o rozmiarze ~ 50 KB do prostej zmiany klasy, jeśli wykonujesz znaczną część pracy JavaScript lub coś, co może mieć niezwykłe zachowanie w różnych przeglądarkach, warto się zastanowić.

(Z grubsza rzecz biorąc, biblioteka to zestaw narzędzi przeznaczonych do określonego zadania, podczas gdy środowisko ogólnie zawiera wiele bibliotek i wykonuje pełen zestaw obowiązków.)

Powyższe przykłady zostały odtworzone poniżej przy użyciu jQuery, prawdopodobnie najczęściej używaną bibliotekę JavaScript (choć są też inne, które warto zbadać).

(Zauważ, że $ tutaj jest obiekt jQuery.)

Zmienianie klas za pomocą jQuery:

$('#MyElement').addClass('MyClass');

$('#MyElement').removeClass('MyClass');

if ( $('#MyElement').hasClass('MyClass') )

Ponadto jQuery zapewnia skrót do dodawania klasy, jeśli nie ma ona zastosowania, lub usuwania klasy, która:

$('#MyElement').toggleClass('MyClass');


Przypisywanie funkcji do zdarzenia kliknięcia za pomocą jQuery:

$('#MyElement').click(changeClass);

lub bez potrzeby identyfikatora:

$(':button:contains(My Button)').click(changeClass);



3302
2017-10-12 20:45



Świetna odpowiedź Peter. Jedno pytanie ... dlaczego tak jest lepszy zrobić z JQuery niż JavaScript? JQuery jest świetny, ale jeśli to wszystko, co musisz zrobić - co usprawiedliwia włączenie całego libracera JQuery zamiast kilku linii JavaScript? - mattstuehler
@mattstuehler 1) wyrażenie "jeszcze lepiej x" często oznacza "jeszcze lepiej (możesz) x". 2) Aby dostać się do sedna sprawy, jQuery został zaprojektowany, aby pomóc w dostępie do DOM / manipulowaniu nim, i bardzo często, jeśli musisz robić tego rodzaju rzeczy, gdy musisz zrobić to wszędzie. - Barry
Jeden błąd z tym rozwiązaniem: Kiedy klikniesz przycisk kilka razy, doda on klasę "MyClass" do elementu wiele razy, zamiast sprawdzać, czy już istnieje. W ten sposób możesz uzyskać atrybut klasy HTML wyglądający mniej więcej tak: class="button MyClass MyClass MyClass" - Web_Designer
Jeśli próbujesz usunąć klasę "myClass" i masz "prefix-myClass" klasy, regex, który podałeś powyżej, aby usunąć klasę, zostawi ci "prefix" w twoim className: O - jinglesthula
Wow, trzy lata i 183 przegrywki i nikt nie zauważył tego aż do teraz. Dzięki jinglesthula, poprawiłem wyrażenie regularne, więc nie spowoduje to nieprawidłowego usunięcia części nazw klas. // Sądzę, że jest to dobry przykład tego, dlaczego warto korzystać z Framework (jak jQuery) - błędy takie jak te są wcześniej łapane i naprawiane i nie wymagają zmian w normalnym kodzie. - Peter Boughton


Możesz także po prostu zrobić:

document.getElementById ("id"). classList.add ("klasa");
document.getElementById ('id'). classList.remove ("klasa");

Aby przełączyć klasę (usuń, jeśli istnieje, dodaj ją):

document.getElementById ('id'). classList.toggle ("klasa");

380
2017-08-05 17:44



Wierzę, że zależy to od HTML5. - John
Będziesz potrzebował Eli Greya classList shim. - ELLIOTTCABLE
Warto zauważyć, że to nie działa w wersjach IE poniżej 8 .. - Lloyd
Mozilla Developer Network stwierdza, że ​​nie działa on natywnie w przeglądarce Internet Explorers mniejszej niż 10. W moim teście stwierdzam, że stwierdzenie jest prawdziwe. Najwyraźniej Eli Grey podkłada jest wymagany w przeglądarce Internet Explorer 8-9. Niestety nie mogłem go znaleźć na jego stronie (nawet przy wyszukiwaniu). Podkładka jest dostępna na łączu Mozilla. - doubleJ
atow "classList" ma częściowe wsparcie w IE10 +; brak obsługi Opera Mini; jeszcze pełne wsparcie w pozostałych standardowych przeglądarkach: caniuse.com/#search=classlist - Nick Humphrey


W jednym z moich starych projektów, które nie używają jQuery, zbudowałem następujące funkcje do dodawania, usuwania i sprawdzania, czy element ma klasę:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(ele, cls) {
    if (!hasClass(ele, cls)) ele.className += " " + cls;
}
function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

Na przykład, jeśli chcę, aby na stronie dodano kilka klas, przycisk ten można użyć:

<script type="text/javascript">
    function changeClass(btn, cls) {
        if(!hasClass(btn, cls)) {
            addClass(btn, cls);
        }
    }
</script>
...
<button onclick="changeClass(this, "someClass")">My Button</button>

Do tej pory na pewno lepiej byłoby użyć jQuery.


98
2018-05-28 07:32



To jest świetne, gdy twój klient nie pozwala ci używać jQuery. (W efekcie prawie tworzymy własną bibliotekę.) - Mike
@Mike Jeśli klient nie zezwala na korzystanie z jQuery, czy nie wystarczy, że przełączysz i przebudujesz tylko te funkcje, które były potrzebne w twojej własnej bibliotece? - kfrncs
@kfrncs Ponieważ generalnie nie potrzebuję tak dużej struktury. Dla projektu, o którym myślałem, jedynymi funkcjami, których potrzebowałem były funkcje 3 classname (has, add, remove) oraz funkcje cookie (has, add, remove). Cała reszta była albo niestandardowa, albo natywnie dobrze obsługiwana. Więc wszystko razem było wtedy tylko 150 liniami przed zminimalizowaniem, włączając komentarze. - Mike
Koleś, jego 4 nad ranem i dziękuję bardzo. Vanilla JS jest tym, czego używamy w moim projekcie i to było życie ratunkowe. - LessQuesar
To moje ulubione rozwiązanie. Używam go wszędzie. Uważam, że jest to najbardziej elegancki sposób na dodawanie i usuwanie klas, gdy twój projekt nie ma jeszcze innego sposobu na zrobienie tego. - WebWanderer


Możesz użyć node.className jak na przykład:

document.getElementById('foo').className = 'bar';

Powinno to działać w IE5.5 i wyżej zgodnie z PPK.


64
2017-10-12 20:33



to zastąpiłoby wszystkie inne klasy obiektu ... więc nie jest to takie proste. - Eric Sebasta


Wow, zaskoczony, jest tu tak wiele przesadnych odpowiedzi ...

<div class="firstClass" onclick="this.className='secondClass'">

46
2018-01-05 19:14



tak, ale dyskretny javascript jest lepszą praktyką. - Lloyd
Powiedziałbym, że dyskretny javascript jest okropną praktyką do pisania przykładowego kodu ... - Gabe
Nie zgodziłbym się, ponieważ myślę, że przykładowy kod powinien dawać dobry przykład. - thomasrutter
Dobry przykład powinien instruować i pobudzać wyobraźnię w tym samym czasie. Nie powinno to zastępować myśli, ale inspirować. - Anthony Rutledge
Pozostałe odpowiedzi nie są przesadą, utrzymują również istniejące klasy na elemencie. - gcampbell


Korzystanie z czystego kodu JavaScript:

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

function addClass(ele, cls) {
    if (!this.hasClass(ele, cls)) ele.className += " " + cls;
}

function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

function replaceClass(ele, oldClass, newClass){
    if(hasClass(ele, oldClass)){
        removeClass(ele, oldClass);
        addClass(ele, newClass);
    }
    return;
}

function toggleClass(ele, cls1, cls2){
    if(hasClass(ele, cls1)){
        replaceClass(ele, cls1, cls2);
    }else if(hasClass(ele, cls2)){
        replaceClass(ele, cls2, cls1);
    }else{
        addClass(ele, cls1);
    }
}

40
2017-09-20 15:26



Tak samo jak tutaj: snipplr.com/view/3561/addclass-removeclass-hasclass - Jaider


To działa dla mnie:

function setCSS(eleID) {
    var currTabElem = document.getElementById(eleID);

    currTabElem.setAttribute("class", "some_class_name");
    currTabElem.setAttribute("className", "some_class_name");
}

27
2017-12-08 09:36



Doskonała odpowiedź! Aby dodać: Ustaw dla każdej nazwy klasy CSS selektora, aby określić styl dla grupy elementów klasy - Roman Polen.
Działa to dla mnie na FF, ale kiedy próbowałem użyć el.className = "newStyle"; to nie zadziałało, dlaczego? - Lukasz 'Severiaan' Grela
Możesz użyć el.setAttribute('class', newClass) albo lepiej el.className = newClass. Ale nie el.setAttribute('className', newClass). - Oriol


Można również rozszerzyć obiekt HTMLElement, aby dodać metody dodawania, usuwania, przełączania i sprawdzania klas (sens):

HTMLElement = typeof(HTMLElement) != 'undefiend' ? HTMLElement : Element;

HTMLElement.prototype.addClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    if (string[i] && !new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)').test(this.className)) {
      this.className = this.className.trim() + ' ' + string[i];
    }
  }
}

HTMLElement.prototype.removeClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    this.className = this.className.replace(new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)'), ' ').trim();
  }
}

HTMLElement.prototype.toggleClass = function(string) {
  if (string) {
    if (new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className)) {
      this.className = this.className.replace(new RegExp('(\\s+|^)' + string + '(\\s+|$)'), ' ').trim();
    } else {
      this.className = this.className.trim() + ' ' + string;
    }
  }
}

HTMLElement.prototype.hasClass = function(string) {
  return string && new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className);
}

A potem po prostu użyj tego (po kliknięciu doda lub usunie klasę):

document.getElementById('yourElementId').onclick = function() {
  this.toggleClass('active');
}

Tutaj jest próbny.


16
2018-04-11 10:13



ten jest trochę gadatliwy ... tutaj jest bardzo zwięzłe rozwiązanie ...jsfiddle.net/jdniki/UaT3P - zero_cool
Sorry @ Jackson_Sandland, ale całkowicie pomijasz punkt, który w ogóle nie ma zastosowania w jQuery. - moka


Aby dodać informacje z innej popularnej platformy, Google Closures, zobacz ich dom / klasy klasa:

goog.dom.classes.add(element, var_args)

goog.dom.classes.addRemove(element, classesToRemove, classesToAdd)

goog.dom.classes.remove(element, var_args)

Używana jest jedna opcja wyboru elementu goog.dom.query z selektorem CSS3:

var myElement = goog.dom.query("#MyElement")[0];

15
2017-11-26 21:04





Kilka drobnych uwag i poprawek w poprzednich wyrażeń regularnych:

Będziesz chciał zrobić to globalnie na wypadek, gdyby lista klas miała nazwę klasy więcej niż jeden raz. Prawdopodobnie będziesz chciał usunąć spacje z końców listy klas i przekonwertować wiele spacji na jedną spację, aby nie uzyskiwać spacji. Żadna z tych rzeczy nie powinna stanowić problemu, jeśli jedyny kod dinking z nazwami klas używa wyrażeń regularnych poniżej i usuwa nazwę przed jej dodaniem. Ale. Cóż, kto wie, kto może wymyślać listę klas.

To wyrażenie regularne nie rozróżnia wielkości liter, więc błędy w nazwach klas mogą pojawiać się przed użyciem kodu w przeglądarce, która nie dba o sprawy w nazwach klas.

var s = "testing   one   four  one  two";
var cls = "one";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "test";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "testing";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "tWo";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");

13
2018-05-02 04:59





Zmień klasę CSS elementu z włączoną obsługą JavaScript ASP.NET:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        lbSave.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
        lbSave.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
        lbCancel.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
        lbCancel.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
    End If
End Sub

12
2018-05-28 07:19



Wiedziałem, że był powód, dla którego nienawidziłem pracy z ASP.NET. - iandisme