HTML5: ukládáme si data k elementům

Už jste se někdy přistihli, že si ukládáte informace k dalšímu zpracování k elementům do atributů rel nebo class? Pokud ano, máme pro vás skvělé novinky: v HTML5 si můžete uložit libovolné informace do vlastních atributů, které jsou pro toto použití přímo určené. Pojďme si ukázat, jak na to.
Seriál: Webdesignérův průvodce po HTML5 (21 dílů)
- Webdesignérův průvodce po HTML5 – díl nultý 25. 5. 2010
- Webdesignérův průvodce po HTML5 – nová sémantika 1. 6. 2010
- Webdesignérův průvodce po HTML5 – nová sémantika II 8. 6. 2010
- Webdesignérův průvodce po HTML5 – pohyblivé obrázky 15. 6. 2010
- Webdesignérův průvodce po HTML5 – používáme pohyblivé obrázky 22. 6. 2010
- Webdesignérův průvodce po HTML5 – taháme data od návštěvníka 29. 6. 2010
- HTML5 Audio: rádio ve vašich stránkách 13. 7. 2010
- Webdesignérův průvodce po HTML5: Microdata 20. 7. 2010
- AppCache: webové aplikace i bez připojení 27. 7. 2010
- Webdesignérův průvodce po HTML5: WebStorage 3. 8. 2010
- Webdesignérův průvodce po HTML5: Multithreading s WebWorkers 10. 8. 2010
- Webdesignérův průvodce po HTML5: Databáze v prohlížečích 17. 8. 2010
- Webdesignérův průvodce po HTML5: Shrnutí a rozhrnutí 24. 8. 2010
- HTML5: ukládáme si data k elementům 6. 12. 2010
- Webdesignérův průvodce po HTML5: Táhni a srůstej 5. 1. 2011
- HTML5: První krůčky s FileSystem API 15. 2. 2011
- Mobilizujeme web v HTML5 4. 4. 2011
- Single Page Apps a řešení problémů s historií 1. 6. 2011
- Page Visibility API: Kouká na mě vůbec někdo? 10. 8. 2011
- Práce se soubory v prohlížeči, díl 1 15. 8. 2011
- Práce se soubory v prohlížeči, díl 2 5. 9. 2011
Nálepky:
Tento text je překladem článku HTML5 Custom Data Attributes z webu HTML5Doctor, autor Chris Bewick. Článek je zveřejněn pod licencí CC-BY-NC.
V HTML5 máme nyní možnost vložit vlastní datové atributy do HTML elementů. Tyto atributy se skládají z dvou částí:
- Jméno atributu
- Jméno atributu musí být minimálně jeden znak dlouhé a musí začínat prefixem ‚
data-
‘. Neměl by obsahovat velká písmena - Hodnota atributu
- Hodnotou atributu může být libovolný řetězec.
Pomocí této syntaxe můžeme přidat vlastní data do HTML kódu, a to takto:
<ul id="semena-zelenina"> <li data-rozestup="10cm" data-cas-setby="Březen až červen">Mrkev</li> <li data-rozestup="30cm" data-cas-setby="Únor až březen">Celer</li> <li data-rozestup="3cm" data-cas-setby="Březen až září">Ředkvičky</li> </ul>
K takto uloženým datům můžeme přistupovat pomocí JavaScriptu. Můžeme je využít např. k tomu, že uživateli se při kliknutí na zeleninu zobrazí okno s informacemi o období setí a o rozestupu mezi semeny. Díky atributům data-
, které jsme přidali k elementům <li>
, můžeme tyto informace zobrazit přímo, bez nutnosti volat Ajaxem server a dotazovat se na ně.
Tím, že atributy začínají prefixem data-
je zajištěno, že je bude prohlížeč ignorovat.
Specifikace říká (zvýraznil autor):
Uživatelské datové atributy jsou určeny k ukládání soukromých uživatelských dat do stránky či aplikace v případech, kdy pro ně není určen specifický element či atribut.
Tyto atributy nejsou určeny pro využití nezávislým softwarem, který není součástí stránky, na níž jsou atributy využity.
Každý HTML element může mít libovolný počet datových atributů libovolné hodnoty.
Jak můžeme použít datové atributy?
Uživatelské datové atributy jsou součástí specifikace HTML5 a jsou správně zpracovány (tj. ignorovány) ve všech prohlížečích, které podporují HTML5 doctype. Naštěstí je takových už většina. Zároveň tento zápis pomáhá zpětné kompatibilitě tím, že zůstanou nezměněné i v budoucnu, že např. nevzniknou kolize s nově přidanými atributy.
Teď máme tedy představu o tom, co datové atributy jsou. Pojďme se podívat na to, jak je můžeme použít:
- K uložení úvodních rozměrů nebo průhlednosti prvku, které později použijeme v javaScriptu k animaci
- K uložení parametrů pro Flash, který bude později načten JavaScriptem
- K uložení uživatelských značek k analýze (viz ukázka od Jasona Karnse)
- K uložení informací o zdraví, munici či životech v JS hrách
- K vytvoření přístupných titulků pro element
<video>
(viz demonstrace od Bruce Lawsona)
K čemu bychom datové atributy neměli používat?
Datové atributy jsou sice flexibilní, ale nejsou vhodné pro každý problém.
- Datový atribut by neměl být použit, pokud existuje ve specifikaci atribut nebo element, který odpovídá přesněji účelu či smyslu uložených dat. Například datum by mělo být uloženo v odpovídajícím elementu, ne v datovém atributu.
- Uživatelské datové atributy nejsou náhradou či konkurencí mikroformátů či mikrodat. Ve specifikaci je jasně řečeno, že nejsou určeny pro veřejné použití a externí software by je neměl nijak využívat. Vyznačit pomocí datových atributů např. kontaktní údaje nebo informace o události není vhodné – samosebou s výjimkou situace, kdy tyto informace mají být použity pouze ve skriptech na téže stránce.
- Přítomnost či nepřítomnost nějakého datového atributu by neměla být využívána jako rozlišující vlastnost v CSS selektoru. Pokud se do takové situace dostanete, znamená to, že tato data jsou nějak důležitá pro prezentaci, a měly by tedy být prezentovány jiným, sémantičtějším a přístupnějším způsobem.
Použití atributů data-
s JavaScriptem
Víme jak uživatelské datové atributy data-
vypadají a kde by měly či naopak neměly být použity. Podíváme se tedy na způsob, jakým mohou být použity s JavaScriptem.
Pokud chceme zjistit nebo změnit hodnotu atributů pomocí JavaScriptu, můžeme použít metody getAttribute
a setAttribute
, viz příklad:
<div id='strawberry-plant' data-fruit='12'></div> <script> // 'Getting' data-attributes using getAttribute var plant = document.getElementById('strawberry-plant'); var fruitCount = plant.getAttribute('data-fruit'); // fruitCount = '12' // 'Setting' data-attributes using setAttribute plant.setAttribute('data-fruit','7'); // Pesky birds </script>
Tato metoda bude fungovat ve všech moderních prohlížečích, ale není to způsob, jaký je pro atributy data-
zamýšlený. Druhý, nový a vylepšený, způsob přistupování k atributům využívá přístup k vlastnosti dataset
u daného elementu. Vlastnost dataset
– která je součástí nově definovaného JS API v HTML5 – vrátí objekt DOMStringMap
, obsahující všechny atributy data-
u daného elementu. Když použijeme tento přístup místo plného jména atributu, můžete prostě odtrhnout prefix data-
a odkazovat se přímo jménem, které atribut má. Atributy, které obsahují spojovník (-), budou převedeny do podoby bez spojovníků, zapsané v CamelCase.
<div id='sunflower' data-leaves='47' data-plant-height='2.4m'></div> <script> // 'Getting' data-attributes using dataset var plant = document.getElementById('sunflower'); var leaves = plant.dataset.leaves; // leaves = 47; // 'Setting' data-attributes using dataset var tallness = plant.dataset.plantHeight; // 'plant-height' -> 'plantHeight' plant.dataset.plantHeight = '3.6m'; // Cracking fertiliser </script>
Když se v nějakém místě vašeho skriptu stane určitý atribut data-
nadbytečným a nebudete jej už v budoucnu potřebovat, můžete jeho hodnotu nastavit na null
a tím jej odstranit z DOMu.
plant.dataset.leaves = null; // Caterpillars attack!
Naneštěstí je vlastnost dataset
implementována zatím jen v některých prohlížečích (dle mých testů v Chrome ano, ve FF3.6 ne – pozn. překl.), takže zatím je potřeba si vystačit s přístupem pomocí getAttribute
a setAttribute
, jak jsme si ukázali výše.
Při vývoji aplikace můžete zjistit, že by se vám hodilo mít možnost vybrat elementy podle přítomnosti (či konkrétní hodnoty) uživatelského data-
atributu. Využijte k tomu metodu querySelectorAll
, jak je ukázáno v následujícím kódu:
// Select all elements with a 'data-flowering' attribute document.querySelectorAll('[data-flowering]'); // Select all elements with red leaves document.querySelectorAll('[data-foliage-colour="red"]');
Varování
Pokud se datové atributy stanou šířeji používanými, zvýší se i riziko konfliktů. pokud budete používat neinvenční jména jako data-height
, pak je velmi velká pravděpodobnost, že se dostanete do konfliktu s nějakou knihovnou, navrženou podobně líným programátorem. Proto je rozumné jména atributů ozdobit, tj. přidat jim specifickou součást jména, například označení knihovny či jméno stránky. Příklad: data-html5doctor-height
nebo data-my-plugin-height
.
Shrnutí
Uživatelské datové atributy jsou výbornou možností, jak zjednodušit ukládání některých aplikačních dat ve webových stránkách. K přístupu použijte getAttribute
a setAttribute
, nebo tam, kde to je možné, vlastnost dataset
.
Dodatek
Pokud si chcete vyzkoušet novou vlastnost dataset
i v prohlížečích, kde zatím není implementována, nemusíte být smutní, protože tu je řešení. Možná vás zaujme ukázkový kód, který simuluje chování vlastnosti dataset
v některých prohlížečích pomocí úpravy Element.prototype
.
Kód podporuje přístup k atributům data-
ve Firefoxu, Safari, Opeře i Chrome, ale bohužel ne v IE, protože IE neumožňuje přístup k objektu Element (netestoval jsem s poslední verzí IE – pozn.překl.). Tento kód umožňuje i nastavit datový atribut, ale nově uložené hodnoty jsou drženy v JavaScriptu a nemění hodnoty v DOMu tak, jak to dělá implementace dataset
. Ačkoli jde spíš o ukázku konceptu, může být užitečný při vývoji v intranetu či u mobilních aplikací, tedy v prostředích, kde není požadována kompatibilita s IE.
Můžu se zeptat co to znamená, že by jméno atributu nemělo obsahovat velká písmena? Co se stane když je použiju?
Předpokládám (netestoval jsem), že se nestane nic závažného – jen nebudete moct rozlišit mezi „data-elce-pelce“ a „data-elcePelce“, kvůli zmíněné konverzi spojovníků na camelCase zápis.
Ahoj,
jsem zvyklý do datových atributů odkazů, které v administraci něco mažou, ukládat potvrzovací otázku typu „Chcete opravdu smazat článek <název>?“.
Narazil jsem ale na dva problémy:
1) Co když bych v té otázce chtěl např. název článku tučně? Celá otázka by pak nemohla být pouze text, ale HTML. Jak se HTML do těchto atributů má ukládat? Nebo bych tu otázku měl raději dát do skrytého elementu dovnitř odkazu?
2) Odkazy s konfirmační otázkou používají mírně odlišné CSS, zatím jsem to řešil selektorem *[data-confirm], což mi ale od začátku nepřipadalo čisté a tento článek to potvrzuje.
Jak toto tedy řešit?
ad 1. — elegantní řešení by samozřejmě bylo dovolit v HTML používat kdekoliv elementy a atributy ve vlastních jmenných prostorech. Do vlastního elementu byste si mohl uložit cokoliv. Bohužel hlavní lidé za HTML5 mají pupínky z XML, takže tuto možnost vytrvale blokují. Výsledkem jsou dost omezené data-atributy.
Nicméně podle přesvědčení těchto lidí je naprosto v pořádku, do atributu vkládat fragmenty HTML kódu. Takový atribut je i v návrhu HTML5 (@srcdoc): http://dev.w3.org/html5/spec-author-view/the-iframe-element.html#attr-iframe-srcdoc
Ve vašem případě tedy můžete použít něco jako:
<button data-confirm=“Chcete opravdu smazat článek <b>Ze života hmyzu</b>?“ …>
Konec konců v HTML zase tolik nevadí, že v atributu máte serializované HTML, protože v Javascriptu to lze kdykoliv naparsovat a vložit do DOMu pomocí innerHTML.
ad 2. — nechápu co vám na tom *[data-confirm] přijde špatné? Samozřejmě o chlup čistší by asi bylo
<button class=“confirm“ data-confirm=“Chcete opravdu smazat článek <b>Ze života hmyzu</b>?“ …>
a v CSS používat .confirm, ale je tam zbytečná duplicita.
ad 1. Naštěstí Vám, i panu Koskovi tito opupínkovaní lídé dovolí zaslat HTML5 dokument s content typem, který patří XHTML (např. application/xml nebo application/xhtml+xml) a voila – máte validní HTML5 dokument v XHTML serializaci :). Do kterého si samozřejmě můžete narvat elementy a atributy z vlastních namespaces.
Nepředpokládám, že by se někdy nějak masově rozšířilo zasílání XHTML dokumentů s jiným MIME typem než text/html, takže omezené možnosti rozšiřitelnosti HTML5 jsou problém.
(z ofic. dokumentace)
„As of jQuery 1.4.3 HTML 5 data- attributes will be automatically pulled in to jQuery’s data object.“
http://api.jquery.com/data/
Ta ukázka nefunguje v IE ještě z dalších důvodů – např. použití nestandardního __defineGetter__ (od IE9 je možné použít defineProperty), použití addEventListener/removeEventListener natvrdo (IE chce attachEvent/detachEvent).
Celkově vzato, je to kandidát na zapouzdření v nějakém frameworku…