Lekcja 11.3: Atrybuty danych (data-*)
Przechowywanie niestandardowych danych w HTML
HTML5 wprowadził mechanizm pozwalający na osadzanie niestandardowych atrybutów danych bezpośrednio w elementach HTML. Atrybuty te, znane jako atrybuty danych (data attributes), służą do przechowywania dodatkowych informacji lub metadanych, które nie mają standardowego semantycznego znaczenia, ale mogą być przydatne dla skryptów JavaScript lub stylów CSS.
Główną zaletą atrybutów danych jest to, że pozwalają one na przechowywanie informacji specyficznych dla aplikacji lub strony bezpośrednio w strukturze DOM, bez konieczności uciekania się do niestandardowych, niepoprawnych atrybutów czy globalnych zmiennych JavaScript.
Składnia atrybutów danych
Atrybuty danych mają specyficzną składnię:
- Nazwa atrybutu musi zaczynać się od prefiksu
data-
. - Po prefiksie
data-
musi następować co najmniej jeden znak. - Nazwa atrybutu (po
data-
) nie może zawierać wielkich liter (ASCII uppercase letters). - Nazwa atrybutu powinna składać się z małych liter, cyfr, myślników (
-
), kropek (.
), dwukropków (:
) lub podkreśleń (_
). Zaleca się używanie myślników do oddzielania słów (kebab-case). - Wartość atrybutu jest dowolnym ciągiem znaków.
Przykłady poprawnych atrybutów danych:
<div data-user-id="12345" data-role="admin" data-last-login="2025-04-29">...</div>
<button data-action="show-details" data-target-element="#info-box-1">Pokaż szczegóły</button>
<li data-animal-type="mammal" data-is-endangered="true">Panda wielka</li>
Dostęp do atrybutów danych w JavaScript
Najwygodniejszym sposobem dostępu do atrybutów danych w JavaScript jest użycie właściwości dataset
dostępnej dla elementów HTML (HTMLElement.dataset
).
Właściwość dataset
zwraca obiekt (DOMStringMap
), który zawiera wszystkie atrybuty data-*
danego elementu. Nazwy atrybutów w obiekcie dataset
są konwertowane z formatu kebab-case (np. data-user-id
) na camelCase (np. userId
).
Przykład odczytu danych:
<div id="profil" data-user-id="987" data-user-name="Anna" data-account-status="active">Profil użytkownika</div>
<script>
const profilDiv = document.getElementById('profil');
// Odczyt danych za pomocą dataset
const userId = profilDiv.dataset.userId; // "987"
const userName = profilDiv.dataset.userName; // "Anna"
const status = profilDiv.dataset.accountStatus; // "active"
console.log(`ID użytkownika: ${userId}, Nazwa: ${userName}, Status: ${status}`);
// Można też odczytać za pomocą getAttribute (mniej wygodne)
const userIdAlt = profilDiv.getAttribute('data-user-id'); // "987"
console.log(`ID (getAttribute): ${userIdAlt}`);
</script>
Przykład modyfikacji i dodawania danych:
<div id="produkt" data-product-id="p101" data-price="19.99">Produkt A</div>
<script>
const produktDiv = document.getElementById('produkt');
// Odczyt ceny
let cena = parseFloat(produktDiv.dataset.price);
console.log(`Cena początkowa: ${cena}`);
// Modyfikacja ceny (wartość jest zawsze stringiem!)
produktDiv.dataset.price = (cena * 0.9).toFixed(2); // Obniżka o 10%
console.log(`Nowa cena (w data-price): ${produktDiv.dataset.price}`);
// Dodanie nowego atrybutu data-*
produktDiv.dataset.category = 'elektronika'; // Stworzy atrybut data-category="elektronika"
console.log(`Dodana kategoria: ${produktDiv.dataset.category}`);
// Usunięcie atrybutu data-*
delete produktDiv.dataset.productId;
console.log(`Czy istnieje data-product-id? ${'productId' in produktDiv.dataset}`); // false
</script>
Ważne: Wartości przechowywane w atrybutach danych są zawsze traktowane jako ciągi znaków (string). Jeśli przechowujesz liczby lub wartości logiczne, musisz je odpowiednio przekonwertować (np. za pomocą parseInt()
, parseFloat()
, lub porównania === 'true'
) podczas odczytu w JavaScript.
Dostęp do atrybutów danych w CSS
Atrybuty danych mogą być również wykorzystywane w CSS do stylizowania elementów lub wyświetlania ich wartości.
- Selektory atrybutów: Można używać standardowych selektorów atrybutów do wybierania elementów na podstawie ich atrybutów danych.
/* Wybierz wszystkie elementy z atrybutem data-status */ [data-status] { border-left: 5px solid gray; } /* Wybierz elementy z data-status="active" */ [data-status="active"] { border-left-color: green; } /* Wybierz elementy z data-role="admin" */ [data-role="admin"]::before { content: "(Admin) "; font-weight: bold; color: red; }
- Funkcja `attr()`: Pozwala na pobranie wartości atrybutu (w tym
data-*
) i użycie jej w właściwościach CSS, najczęściej w połączeniu z pseudoelementem::before
lub::after
i właściwościącontent
./* Wyświetl wartość data-tooltip jako podpowiedź po najechaniu */ [data-tooltip]::after { content: attr(data-tooltip); /* ... dodatkowe style dla tooltipa ... */ display: none; /* Ukryj domyślnie */ position: absolute; /* ... */ } [data-tooltip]:hover::after { display: block; /* Pokaż po najechaniu */ }
Przykładowe zastosowania
- Przechowywanie unikalnych identyfikatorów (np. ID z bazy danych) powiązanych z elementem.
- Konfiguracja pluginów JavaScript (np.
data-slider-speed="500"
). - Przechowywanie stanu elementu (np.
data-status="expanded"
). - Tworzenie "haków" dla CSS bez używania klas (np.
data-color="blue"
). - Przechowywanie danych potrzebnych do dynamicznych interakcji (np. URL do zapytania AJAX).
Zadanie praktyczne (z rozwiązaniem)
Zadanie: Utwórz listę <ul>
z trzema elementami <li>
reprezentującymi różne owoce. Do każdego <li>
dodaj atrybuty data-color
(kolor owocu) i data-calories
(liczba kalorii). Następnie użyj JavaScript, aby po kliknięciu na element listy, w konsoli wyświetlić jego kolor i kaloryczność.
Rozwiązanie:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Atrybuty Danych - Owoce</title>
<style>
ul { list-style: none; padding: 0; }
li { padding: 10px; border: 1px solid #eee; margin-bottom: 5px; cursor: pointer; }
li:hover { background-color: #f0f0f0; }
/* Dodatkowy styl wykorzystujący data-color */
li[data-color="red"] { border-left: 5px solid red; }
li[data-color="yellow"] { border-left: 5px solid yellow; }
li[data-color="green"] { border-left: 5px solid green; }
</style>
</head>
<body>
<h1>Kliknij na owoc, aby zobaczyć informacje:</h1>
<ul id="lista-owocow">
<li data-color="red" data-calories="52">Jabłko</li>
<li data-color="yellow" data-calories="89">Banan</li>
<li data-color="green" data-calories="60">Gruszka</li>
</ul>
<script>
const listaOwocow = document.getElementById('lista-owocow');
listaOwocow.addEventListener('click', function(event) {
// Sprawdź, czy kliknięto na element LI
if (event.target.tagName === 'LI') {
const owoc = event.target;
const kolor = owoc.dataset.color;
const kalorie = parseInt(owoc.dataset.calories, 10); // Konwersja na liczbę
console.log(`Wybrano: ${owoc.textContent}`);
console.log(`Kolor: ${kolor}`);
console.log(`Kalorie: ${kalorie}`);
console.log('---');
}
});
</script>
</body>
</html>
Po otwarciu tej strony i kliknięciu na poszczególne owoce, w konsoli deweloperskiej przeglądarki pojawią się odpowiednie informacje o kolorze i kaloryczności, odczytane z atrybutów data-*
.
Dodatkowe zadania do samodzielnego wykonania:
- Zmodyfikuj powyższy przykład tak, aby zamiast w konsoli, informacje o owocu wyświetlały się w osobnym elemencie
<div>
na stronie. - Dodaj do elementów listy atrybut
data-is-available="true"
lubdata-is-available="false"
. Użyj CSS, aby przekreślić nazwę owocu, jeśli jest niedostępny (data-is-available="false"
). - Utwórz przycisk z atrybutem
data-target-url="/api/data"
. Napisz skrypt JavaScript, który po kliknięciu przycisku odczyta ten URL i (symulacyjnie) wykona zapytanie pod ten adres.
Najczęściej zadawane pytania
Do czego służą atrybuty danych (data-*)?
Do przechowywania niestandardowych informacji lub metadanych bezpośrednio w elementach HTML, które mogą być później wykorzystane przez JavaScript lub CSS.
Jak nazywać atrybuty danych?
Nazwa musi zaczynać się od `data-`, nie może zawierać wielkich liter, a po `data-` musi być co najmniej jeden znak. Zaleca się używanie małych liter i myślników (kebab-case), np. `data-user-id`.
Jak odczytać wartość atrybutu data-* w JavaScript?
Najłatwiej użyć właściwości `element.dataset`. Nazwy atrybutów są konwertowane na camelCase, np. `element.dataset.userId` odczyta wartość `data-user-id`.
Czy wartości w atrybutach danych są liczbami?
Nie, wartości są zawsze traktowane jako ciągi znaków (string). Jeśli przechowujesz liczby lub wartości logiczne, musisz je przekonwertować w JavaScript (np. `parseInt()`, `parseFloat()`).
Czy mogę używać atrybutów danych w CSS?
Tak, można ich używać w selektorach atrybutów (np. `[data-status="active"]`) oraz do pobierania wartości za pomocą funkcji `attr()` (np. `content: attr(data-tooltip);`).