Kurs HTML

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ę:

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.

Przykładowe zastosowania

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:

  1. Zmodyfikuj powyższy przykład tak, aby zamiast w konsoli, informacje o owocu wyświetlały się w osobnym elemencie <div> na stronie.
  2. Dodaj do elementów listy atrybut data-is-available="true" lub data-is-available="false". Użyj CSS, aby przekreślić nazwę owocu, jeśli jest niedostępny (data-is-available="false").
  3. 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);`).