3. března 2026

Atributy a vlastnosti

Když prohlížeč načítá stránku, „rozebere“ (jiným slovem: „parsuje“) HTML kód a vygeneruje z něj DOM objekty. U elementových uzlů se pro většinu standardních HTML atributů automaticky vytvoří vlastnosti DOM objektů.

Například jestliže značka je <body id="stránka">, pak DOM objekt obsahuje body.id="stránka".

Avšak ne vždy se jeden atribut mapuje na jednu vlastnost a naopak! V této kapitole budeme věnovat pozornost tomu, jak tyto dva pojmy odlišit, jak s nimi pracovat, kdy jsou stejné a kdy jsou různé.

DOM vlastnosti

Vestavěné DOM vlastnosti jsme už viděli. Je jich spousta. Technicky nás však nic neomezuje, a pokud nám tyto vlastnosti nestačí, můžeme si přidat vlastní.

DOM uzly jsou regulérní JavaScriptové objekty. Můžeme je měnit.

Vytvořme například novou vlastnost v document.body:

document.body.mojeData = {
  jméno: 'Caesar',
  titul: 'Imperátor'
};

alert(document.body.mojeData.titul); // Imperátor

Můžeme přidat i metodu:

document.body.řekniNázevZnačky = function() {
  alert(this.tagName);
};

document.body.řekniNázevZnačky(); // BODY (hodnota „this" v metodě je document.body)

Můžeme také měnit vestavěné prototypy, např. Element.prototype, a přidávat tak nové metody všem elementům:

Element.prototype.řekniAhoj = function() {
  alert(`Ahoj, já jsem ${this.tagName}`);
};

document.documentElement.řekniAhoj(); // Ahoj, já jsem HTML
document.body.řekniAhoj(); // Ahoj, já jsem BODY

DOM vlastnosti a metody se tedy chovají přesně jako vlastnosti a metody obvyklých JavaScriptových objektů:

  • Mohou mít jakoukoli hodnotu.
  • V názvech se rozlišují malá a velká písmena (píšeme elem.nodeType, ne elem.NoDeTyPe).

HTML atributy

Značky v HTML mohou obsahovat atributy. Když prohlížeč parsuje HTML kód a vytváří ze značek DOM objekty, rozpoznává standardní atributy a vytváří pro ně DOM vlastnosti.

Když tedy element obsahuje id nebo jiný standardní atribut, vytvoří se odpovídající vlastnost. Pokud je však atribut nestandardní, nestane se to.

Příklad:

<body id="test" něco="nestandardní">
  <script>
    alert(document.body.id); // test
    // z nestandardních atributů nevznikne vlastnost
    alert(document.body.něco); // undefined
  </script>
</body>

Prosíme všimněte si, že standardní atribut jednoho elementu může být neznámý v jiném. Například "type" je standardní atribut pro <input> (HTMLInputElement), ale ne pro <body> (HTMLBodyElement). Standardní atributy jsou popsány ve specifikaci příslušné třídy elementu.

Zde to vidíme:

<body id="body" type="...">
  <input id="input" type="text">
  <script>
    alert(input.type); // text
    alert(body.type); // undefined: DOM vlastnost nevznikla, protože atribut je nestandardní
  </script>
</body>

Pokud je tedy atribut nestandardní, nebude pro něj vytvořena DOM vlastnost. Je nějaký způsob, jak k takovým atributům přistupovat?

Jistě. Všechny atributy jsou dostupné pomocí následujících metod:

  • elem.hasAttribute(název) – ověří existenci atributu.
  • elem.getAttribute(název) – vrátí jeho hodnotu.
  • elem.setAttribute(název, hodnota) – nastaví jeho hodnotu.
  • elem.removeAttribute(název) – odstraní atribut.

Tyto metody pracují přesně s tím, co je uvedeno v HTML kódu.

Můžeme také načíst všechny atributy pomocí elem.attributes: kolekce objektů, které patří do vestavěné třídy Attr s vlastnostmi name (název) a value (hodnota).

Následuje ukázka načtení nestandardní vlastnosti:

<body něco="nestandardní">
  <script>
    alert(document.body.getAttribute('něco')); // nestandardní
  </script>
</body>

HTML atributy mají následující vlastnosti:

  • V jejich názvech se nerozlišují malá a velká písmena (id je totéž jako ID).
  • Jejich hodnoty jsou vždy řetězce.

Následuje rozsáhlejší ukázka práce s atributy:

<body>
  <div id="elem" téma="Slon"></div>

  <script>
    alert( elem.getAttribute('Téma') ); // (1) 'Slon', čtení

    elem.setAttribute('Test', 123); // (2), zápis

    alert( elem.outerHTML ); // (3), podíváme se, zda je atribut v HTML kódu (je)

    for (let atribut of elem.attributes) { // (4) výpis všech atributů
      alert( `${atribut.name} = ${atribut.value}` );
    }
  </script>
</body>

Prosíme všimněte si:

  1. getAttribute('Téma') – zde je první písmeno velké, zatímco v HTML kódu jsou všechna písmena malá. Na tom však nezáleží: v názvech atributů se velká a malá písmena nerozlišují.
  2. Do atributu můžeme přiřadit cokoli, ale stane se z toho řetězec. Zde tedy máme hodnotu "123".
  3. Všechny atributy včetně těch, které jsme nastavili my, jsou vidět v outerHTML.
  4. Kolekce attributes je iterovatelná a obsahuje všechny atributy elementu (standardní i nestandardní) jako objekty s vlastnostmi name (název) a value (hodnota).

Synchronizace vlastností s atributy

Když se změní standardní atribut, automaticky se aktualizuje příslušná vlastnost a naopak (s určitými výjimkami).

V následujícím příkladu změníme id jako atribut a uvidíme, že se změnila i vlastnost. A pak totéž obráceně:

<input>

<script>
  let input = document.querySelector('input');

  // atribut => vlastnost
  input.setAttribute('id', 'id');
  alert(input.id); // id (aktualizováno)

  // vlastnost => atribut
  input.id = 'novéId';
  alert(input.getAttribute('id')); // novéId (aktualizováno)
</script>

Existují však výjimky, například input.value se synchronizuje jen z atributu do vlastnosti, ale ne obráceně:

<input>

<script>
  let input = document.querySelector('input');

  // atribut => vlastnost
  input.setAttribute('value', 'text');
  alert(input.value); // text

  // NIKOLI vlastnost => atribut
  input.value = 'nováHodnota';
  alert(input.getAttribute('value')); // text (neaktualizováno!)
</script>

V uvedeném příkladu:

  • Po změně atributu value se aktualizovala vlastnost.
  • Ale po změně vlastnosti se atribut nezměnil.

Tato „vlastnost“ se ve skutečnosti může hodit, protože akce uživatele mohou vést ke změně value, a pokud následovně chceme obnovit „původní“ hodnotu z HTML, je stále v atributu.

DOM vlastnosti jsou různých typů

DOM vlastnosti nejsou vždy řetězce. Například vlastnost input.checked (pro checkboxy) je booleovská:

<input id="input" type="checkbox" checked> checkbox

<script>
  alert(input.getAttribute('checked')); // hodnota atributu je: prázdný řetězec
  alert(input.checked); // hodnota vlastnosti je: true
</script>

Jsou i jiné příklady. Atribut style je řetězec, ale vlastnost style je objekt:

<div id="div" style="color:red;font-size:120%">Ahoj</div>

<script>
  // řetězec
  alert(div.getAttribute('style')); // color:red;font-size:120%

  // objekt
  alert(div.style); // [object CSSStyleDeclaration]
  alert(div.style.color); // red
</script>

Většina vlastností však jsou řetězce.

Poměrně vzácně se stává, že i když je DOM vlastnost typu řetězec, může se od atributu lišit. Například DOM vlastnost href je vždy úplné URL, i když atribut obsahuje relativní URL nebo jen #hash.

Zde je příklad:

<a id="a" href="#ahoj">odkaz</a>
<script>
  // atribut
  alert(a.getAttribute('href')); // #ahoj

  // vlastnost
  alert(a.href ); // úplné URL ve tvaru http://site.com/stránka#ahoj
</script>

Jestliže potřebujeme hodnotu href nebo kteréhokoli jiného atributu přesně takovou, jaká je uvedena v HTML, můžeme použít getAttribute.

Nestandardní atributy, vlastnost dataset

Když píšeme HTML kód, používáme spoustu standardních atributů. Ale co ty nestandardní, naše vlastní? Nejprve se podíváme, zda jsou vůbec užitečné. K čemu jsou?

Nestandardní atributy se někdy používají k předávání vlastních dat z HTML do JavaScriptu nebo k „označení“ HTML elementů pro JavaScript.

Třeba takto:

<!-- označíme si div, aby zde zobrazil "jméno" -->
<div zobraz-info="jméno"></div>
<!-- a zde věk -->
<div zobraz-info="věk"></div>

<script>
  // kód najde označený element a zobrazí to, co je požadováno
  let uživatel = {
    jméno: "Petr",
    věk: 25
  };

  for(let div of document.querySelectorAll('[zobraz-info]')) {
    // vložíme odpovídající informaci do pole
    let pole = div.getAttribute('zobraz-info');
    div.innerHTML = uživatel[pole]; // nejprve Petr do "jméno", pak 25 do "věk"
  }
</script>

Můžeme je použít i k nastavení stylu elementu.

Například zde použijeme pro stav objednávky atribut stav-objednávky:

<style>
  /* styly závisejí na našem atributu "stav-objednávky" */
  .objednávka[stav-objednávky="nová"] {
    color: green;
  }

  .objednávka[stav-objednávky="vyřízená"] {
    color: blue;
  }

  .objednávka[stav-objednávky="zrušená"] {
    color: red;
  }
</style>

<div class="objednávka" stav-objednávky="nová">
  Nová objednávka.
</div>

<div class="objednávka" stav-objednávky="vyřízená">
  Vyřízená objednávka.
</div>

<div class="objednávka" stav-objednávky="zrušená">
  Zrušená objednávka.
</div>

Proč bychom měli raději použít atribut než třídy jako .stav-objednávky-nová, .stav-objednávky-vyřízená, .stav-objednávky-zrušená?

Protože s atributem se pohodlněji manipuluje. Takhle snadno můžeme změnit stav:

// trochu jednodušší než odstranit starou/přidat novou třídu
div.setAttribute('stav-objednávky', 'zrušená');

S vlastními atributy však může nastat problém. Co když použijeme pro naše účely nestandardní atribut, který bude později zařazen do standardu a bude něco dělat? Jazyk HTML je živý, neustále se rozrůstá a objevují se další atributy, aby uspokojily potřeby vývojářů. V takovém případě může dojít k neočekávaným efektům.

K tomu, abychom se vyhnuli konfliktům, slouží atributy data-*.

Všechny atributy začínající „data-“ jsou rezervovány pro použití programátory a jsou dostupné ve vlastnosti dataset.

Například jestliže elem obsahuje atribut s názvem "data-téma", bude tento atribut k dispozici jako elem.dataset.téma.

Příklad:

<body data-téma="Sloni">
<script>
  alert(document.body.dataset.téma); // Sloni
</script>

Víceslovné atributy jako data-stav-objednávky budou zapsány velbloudí notací: dataset.stavObjednávky.

Následuje přepsaný příklad se „stavem objednávky“:

<style>
  .objednávka[data-stav-objednávky="nová"] {
    color: green;
  }

  .objednávka[data-stav-objednávky="vyřízená"] {
    color: blue;
  }

  .objednávka[data-stav-objednávky="zrušená"] {
    color: red;
  }
</style>

<div id="objednávka" class="objednávka" data-stav-objednávky="nová">
  Nová objednávka.
</div>

<script>
  // načtení
  alert(objednávka.dataset.stavObjednávky); // nová

  // změna
  objednávka.dataset.stavObjednávky = "vyřízená"; // (*)
</script>

Používání atributů s názvem data-* je platný a bezpečný způsob, jak předávat vlastní data.

Prosíme všimněte si, že datové atributy můžeme nejen číst, ale i měnit. Pak CSS příslušným způsobem aktualizuje zobrazení: v uvedeném příkladu poslední řádek (*) změní barvu na modrou.

Shrnutí

  • Atributy – to, co je uvedeno v HTML.
  • Vlastnosti – to, co je v DOM objektech.

Malé srovnání:

Vlastnosti Atributy
Typ Libovolná hodnota, standardní vlastnosti mají typ popsaný ve specifikaci Řetězec
Název Rozlišují se malá a velká písmena Nerozlišují se malá a velká písmena

Metody pro práci s atributy jsou:

  • elem.hasAttribute(název) – ověření existence.
  • elem.getAttribute(název) – získání hodnoty.
  • elem.setAttribute(název, hodnota) – nastavení hodnoty.
  • elem.removeAttribute(název) – odstranění atributu.
  • elem.attributes je kolekce všech atributů.

Ve většině situací se dává přednost používání DOM vlastností. Na atributy bychom se měli odkazovat jen tehdy, když nám DOM vlastnosti nestačí a potřebujeme přesné hodnoty atributů, například:

  • Potřebujeme nestandardní atribut. Pokud však jeho název začíná data-, měli bychom použít dataset.
  • Chceme načíst hodnotu „tak, jak je uvedena“ v HTML kódu. Hodnota DOM vlastnosti se může lišit, například vlastnost href je vždy úplné URL, ale my můžeme chtít získat „původní“ hodnotu.

Úlohy

důležitost: 5

Napište kód, který z dokumentu vybere element s atributem data-název-widgetu a načte jeho hodnotu.

<!DOCTYPE html>
<html>
<body>

  <div data-název-widgetu="menu">Vyberte žánr</div>

  <script>
    /* váš kód */
  </script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>

  <div data-název-widgetu="menu">Vyberte žánr</div>

  <script>
    // získáme ho
    let elem = document.querySelector('[data-název-widgetu]');

    // načteme hodnotu
    alert(elem.dataset.názevWidgetu);
    // nebo
    alert(elem.getAttribute('data-název-widgetu'));
  </script>
</body>
</html>
důležitost: 3

Obarvěte všechny externí odkazy oranžově změnou jejich vlastnosti style.

Odkaz je externí, jestliže:

  • Jeho href obsahuje ://.
  • Ale nezačíná http://internal.com.

Příklad:

<a name="seznam">seznam</a>
<ul>
  <li><a href="http://google.com">http://google.com</a></li>
  <li><a href="/tutorial">/tutorial.html</a></li>
  <li><a href="local/path">local/path</a></li>
  <li><a href="ftp://ftp.com/my.zip">ftp://ftp.com/my.zip</a></li>
  <li><a href="http://nodejs.org">http://nodejs.org</a></li>
  <li><a href="http://internal.com/test">http://internal.com/test</a></li>
</ul>

<script>
  // nastavíme styl pro jediný odkaz
  let odkaz = document.querySelector('a');
  odkaz.style.color = 'orange';
</script>

Výsledek by měl být:

Otevřít pískoviště pro úlohu.

Nejprve musíme najít všechny externí odkazy.

To lze udělat dvěma způsoby.

První je najít všechny odkazy pomocí document.querySelectorAll('a') a pak vyfiltrovat ty, které potřebujeme:

let odkazy = document.querySelectorAll('a');

for (let odkaz of odkazy) {
  let href = odkaz.getAttribute('href');
  if (!href) continue; // neobsahuje atribut

  if (!href.includes('://')) continue; // neobsahuje protokol

  if (href.startsWith('http://internal.com')) continue; // interní

  odkaz.style.color = 'orange';
}

Prosíme všimněte si, že používáme odkaz.getAttribute('href') a ne odkaz.href, protože potřebujeme hodnotu z HTML kódu.

…Druhý, jednodušší způsob je přidat kontrolu do CSS selektoru:

// najdeme všechny odkazy, které v href obsahují ://
// ale href nezačíná http://internal.com
let selektor = 'a[href*="://"]:not([href^="http://internal.com"])';
let odkaz = document.querySelectorAll(selektor);

odkazy.forEach(odkaz => odkaz.style.color = 'orange');

Otevřít řešení na pískovišti.

Mapa tutoriálu

Komentáře

přečtěte si před komentováním…
  • Máte-li návrhy na zlepšení, vytvořte prosím issue na GitHubu nebo pull request místo komentáře.
  • Pokud v článku něčemu nerozumíte, napište prosím, čemu přesně a na kterém místě.
  • Pro vložení několika slov kódu použijte značku <code>, pro několik řádků je obalte značkou <pre>, pro více než 10 řádků vložte odkaz na pískoviště (plnkr, jsbin, codepen…)