Zaznaczanie aktywnych elementów HTML bez użycia JavaScript
Treść dodana: 08 września 2017.
Często spotykaną sytuacją jest potrzeba zaznaczenia aktywnego elementu po kliknięciu w niego. Nie namyślając się długo, młody adept sztuki web-devu wykorzysta w tym celu jQuery, popełniając jeszcze przy tym kilka dodatkowych błędów. Jako ilustrację omawianej sytuacji można podać grupę przycisków (sformatowanych frameworkiem Twitter Bootstrap):
<div class="btn-group" role="group" aria-label="..."> <button type="button" class="btn btn-default">Left</button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div>
Zazwyczaj unikam w tekście pokazywania złych nawyków, tym razem jednak sądzę że jest to uzasadnione. Nidgy nie używaj takiego kodu produkcyjnie.
$(function() { $("button").click(function() { $("button").removeClass("active"); $(this).addClass("active"); }); });
Kod po kliknięciu w `button` doda klasę `active` do aktywnego (klikniętego) przycisku. Działa? Owszem, ale… Nie wykorzystano delegacji zdarzeń dlatego zdarzenie zostało przypięte po kolei do każdego możliwego elementu `button` na stronie. Przy większej ich liczbie kod będzie wolniej się wykonywał. Gdyby do grupy dodać dynamicznie kolejny przycisk, kod nie będzie dla niego już działał – z tego samego powodu co wcześniej. Następuje niepotrzebna modyfikacja drzewa DOM poprzez zdejmowanie i dodawanie klas. Do działania niezbędna jest biblioteka jQuery – w zminifikowanej i skompresowanej wersji to co najmniej 35kB kodu. Co powinniśmy zrobić żeby podobny efekt uzyskać w samym HTML + CSS?
W pierwszej kolejności powinieneś zapoznać się Czytelniku z dokumentacją CSS dotyczącą selektorów. Oprócz bazowych selektorów które pewnie od dawna znasz, na liście znajduje się pseudo-klasa `:checked` którą można wykorzystać do uzyskania potrzebnego efektu. Ma ona zastosowanie do każdego zaznaczonego przycisku
<input type="radio"/> <input type="checkbox"/>
oraz wybranego elementu `option` wewnątrz listy rozwijanej `select`. Dodatkowo możemy posłużyć się selektorem `E + F`, który wybiera element F bezpośrednio poprzedzony elementem E. Przepisany kod HTML:
<div class="btn-group btn-group-radio" role="group" aria-label="..."> <input type="radio" name="group1" id="button1"/> <label for="button1" class="btn btn-default">Left</label> <input type="radio" name="group1" id="button2"/> <label for="button2" class="btn btn-default">Middle</label> <input type="radio" name="group1" id="button3"/> <label for="button3" class="btn btn-default">Right</label> </div>
Dla rozróżnienia została dodana klasa `btn-group-radio`. Co będzie nam potrzebne od strony CSS? Przede wszystkim musimy ukryć wszystkie przyciski typu `radio`. Do zaznaczenia aktywnego przycisku wystarczy wybranie etykiety `label`. Należy także poprawić zaokrąglenie rogów pierwszego elementu `label`, dla którego style Bootstrap nie zadziałają. Następnie wykorzystując selektor `E + F` zmienimy tło wybranego przycisku na czerwone.
.btn-group-radio input[type="radio"] { display: none; } .btn-group-radio input[type="radio"]:checked + .btn { background-color: red; } .btn-group-radio > .btn { margin-left: -1px; } .btn-group-radio > input:first-child + .btn { border-top-left-radius: 4px !important; border-bottom-left-radius: 4px !important; margin-left: 0; }
Działający kod można zobaczyć na stronie demonstracyjnej. Wystarczyło odrobinę przebudować HTML, dodać kilka linijek CSS i uzyskaliśmy podobny efekt – bez wykorzystania jQuery.
Zmiana stanu widoczności menu
Kolejnym bardzo częstym przypadkiem użycia JavaScript jest pokazywanie / ukrywanie menu. I po raz kolejny wystarczy odrobina kreatywności aby nie angażować skryptów do tego zadania. Przykładowy kod menu może mieć postać:
<!-- label może być umieszczony gdziekolwiek na stronie --> <label for="expand-button" class="btn btn-primary">Pokaż / ukryj menu</label> <input type="checkbox" id="expand-button" /> <nav id="menu"> <ul> <li> <a href="#">Link1</a> </li> <li> <a href="#">Link2</a> </li> <li> <a href="#">Link3</a> </li> </ul> </nav>
Tym razem przyda nam się selektor `E ~ F` – element F poprzedzony elementem E. Idea jest taka, aby `#menu` mogło być osadzone gdziekolwiek na stronie. Aby to działało, `input#expand-button` musi się zawsze znaleźć przed nim w kodzie. Wystarczy teraz kilka linijek CSS i gotowe:
label { cursor: pointer; } #expand-button { display: none; } #expand-button:checked ~ #menu, #expand-button:checked ~ * #menu { display: block; } #menu { display: none; }
Możemy chcieć też dodać animację pojawiającego się menu (czas 2 sekundy):
#expand-button:checked ~ #menu, #expand-button:checked ~ * #menu { visibility: visible; position: static; opacity: 1; animation: fade 2s; } #menu { visibility: hidden; position: absolute; opacity: 0; } @keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; } }
`@keyframes` podałem jako dodatkowy przykład. W zupełności wystarczyłaby sama konstrukcja:
transition: opacity 2s linear;
Podsumowanie
Chociaż CSS pozwala na wiele ciekawych efektów, jest szybki i elastyczny w użyciu, to nie zawsze będziemy w stanie pominąć JavaScript. Podmianę tekstu w przyciskach łatwiej będzie wykonać w JS, do ustalenia stanu aktywnego przycisku potrzebny będzie jakiś `storage` (cookie, session/localStorage) który ponownie odczytamy w tym języku. Programowanie to dziedzina w której ustalenie złotego środka jest zawsze kluczem.
Dodaj komentarz
- sieć
- http
- apache
- ssl
- php
- composer
- javascript
- jquery
- ajax
- html
- pdo
- sql server
- spl
- css
- sql
- mysql
- postresql
- mongodb
- psr
- programowanie
- regex
Wyszukaj interesujące Cię słowa kluczowe pośród istniejących porad.
Komentarze
fajno przyda sie