JavaScript/Frontend

Query Selector

Co je querySelector?

querySelector je moderní JavaScript metoda pro výběr HTML elementů z DOM (Document Object Model) pomocí CSS selektorů. Na rozdíl od starších metod jako getElementById nebo getElementsByClassName, querySelector umožňuje použít libovolný CSS selektor – třídy, ID, atributy, pseudotřídy nebo jejich kombinace. Je to jako CSS, ale místo aplikace stylů vybíráte elementy pro JavaScript manipulaci.

querySelector vrací první nalezený element, který odpovídá zadanému selektoru. Pokud žádný element neexistuje, vrací null. Například document.querySelector('.button') vrátí první element s třídou "button" na stránce. querySelectorAll vrací NodeList všech elementů, které odpovídají selektoru – i když najde 100 elementů. NodeList se chová podobně jako pole, ale není to skutečný Array (nemá metody map, filter), můžete ho ale převést pomocí Array.from() nebo spread operátoru [...nodeList].

querySelector a querySelectorAll byly představeny v DOM Level 4 specifikaci a jsou plně podporovány všemi moderními prohlížeči včetně Internet Explorer 9+ (s některými omezeními). V moderním webovém vývoji jsou preferovanou metodou pro výběr elementů díky jejich flexibilitě a konzistenci s CSS syntaxí. Eliminují potřebu jQuery pro základní DOM manipulaci – vše, co jQuery $ selektor dělal, můžete dělat s querySelector v vanilla JavaScriptu.

Základní syntaxe a použití

Výběr podle třídy:
const button = document.querySelector('.btn');
const allButtons = document.querySelectorAll('.btn');

Výběr podle ID:
const header = document.querySelector('#main-header');
Pozor: Pro ID je rychlejší použít document.getElementById('main-header'), ale querySelector je univerzálnější.

Výběr podle HTML tagu:
const firstParagraph = document.querySelector('p');
const allParagraphs = document.querySelectorAll('p');

Kombinované selektory:
const activeButton = document.querySelector('.btn.active'); - element s oběma třídami
const submit = document.querySelector('button[type="submit"]'); - button s type="submit"
const firstLink = document.querySelector('nav a:first-child'); - první odkaz v nav

Vnořené selektory:
const item = document.querySelector('.container .item'); - .item uvnitř .container (libovolná úroveň)
const child = document.querySelector('.container > .item'); - přímé dítě
const next = document.querySelector('.item + .item'); - následující sourozenec

Volání na elementu (ne pouze document):
const container = document.querySelector('.container');
const item = container.querySelector('.item');
Toto hledá .item pouze uvnitř containeru, ne v celém dokumentu – velmi užitečné pro komponenty a scoped queries.

Rozdíl mezi querySelector a querySelectorAll

  • querySelector - vrací jeden element

  • querySelector vrací první element, který odpovídá selektoru. Pokud na stránce máte 10 tlačítek s třídou .btn, document.querySelector('.btn') vrátí pouze první z nich. Pokud žádný element neodpovídá, vrací null (ne undefined). Používejte když potřebujete pouze jeden konkrétní element nebo víte, že element je na stránce jediný (například #main-header).

  • querySelectorAll - vrací NodeList

  • querySelectorAll vrací NodeList všech elementů, které odpovídají selektoru. NodeList je array-like object (má length a můžete iterovat forEach), ale není to Array. Pro použití array metod jako map, filter převeďte: Array.from(nodeList) nebo [...nodeList]. Pokud žádný element neodpovídá, vrací prázdnou NodeList (ne null). Používejte když potřebujete pracovat s více elementy současně.

  • Statická vs. živá kolekce

  • NodeList z querySelectorAll je statická – pokud po výběru přidáte nebo odeberete elementy z DOM, NodeList se neaktualizuje. Naproti tomu getElementsByClassName vrací HTMLCollection, která je živá – automaticky reflektuje změny v DOM. Statická NodeList je obvykle preferovaná, protože je předvídatelnější a výkonnější.

Srovnání s tradičními metodami

getElementById vs querySelector:
document.getElementById('header') - rychlejší, ale funguje pouze pro ID
document.querySelector('#header') - pomalejší, ale univerzální syntaxe
Pro výkon: pokud vybíráte element podle ID často (například v loope), použijte getElementById. Pro běžné použití je rozdíl zanedbatelný (mikrovteřiny).

getElementsByClassName vs querySelectorAll:
document.getElementsByClassName('btn') - vrací živou HTMLCollection
document.querySelectorAll('.btn') - vrací statickou NodeList
querySelectorAll je preferovaná pro čitelnější a konzistentnější kód. Živá kolekce může způsobit neočekávané chování (například infinite loop při přidávání elementů do kolekce během iterace).

getElementsByTagName vs querySelectorAll:
document.getElementsByTagName('p') - živá HTMLCollection
document.querySelectorAll('p') - statická NodeList
Opět, querySelectorAll je modernější a bezpečnější volba pro většinu use cases.

jQuery $ vs querySelector:
$('.btn').click(handler) - jQuery
document.querySelectorAll('.btn').forEach(btn => btn.addEventListener('click', handler)) - vanilla JS
Moderní JavaScript s querySelector eliminuje potřebu jQuery pro DOM manipulaci v mnoha projektech. querySelector + addEventListener + forEach pokrývá 90 % běžných use cases.

Praktické příklady použití

  • Přidání event listeneru na tlačítko

  • const button = document.querySelector('.submit-btn');
    button.addEventListener('click', () => {
      console.log('Tlačítko kliknuto');
    });
    Nezapomeňte ověřit, že element existuje před přidáním listeneru: if (button) { ... }

  • Změna třídy všem elementům

  • const cards = document.querySelectorAll('.card');
    cards.forEach(card => {
      card.classList.add('active');
    });
    NodeList má forEach metodu nativně (na rozdíl od HTMLCollection), takže nemusíte převádět na Array.

  • Validace formuláře

  • const form = document.querySelector('#contact-form');
    const emailInput = form.querySelector('input[type="email"]');
    const isValid = emailInput.value.includes('@');
    Všimněte si volání querySelector na form elementu – hledá pouze uvnitř formuláře, ne v celém dokumentu.

  • Dynamická manipulace s DOM

  • const container = document.querySelector('.items-container');
    const items = container.querySelectorAll('.item');
    items.forEach((item, index) => {
      item.textContent = `Item ${index + 1}`;
    });
    Kombinace querySelector pro container a querySelectorAll pro items v něm je běžný pattern.

  • Výběr podle atributu data-*

  • const activeTab = document.querySelector('[data-tab="active"]');
    const allTabs = document.querySelectorAll('[data-tab]');
    Data atributy jsou skvělé pro JavaScript hooks – oddělujete styling (.class) od funkcionality ([data-*]).

Performance a best practices

  • Cache selektorů do proměnných

  • Opakované volání querySelector je zbytečné. Uložte výsledek do proměnné:
    ❌ Špatně: document.querySelector('.btn').addEventListener(...)
    document.querySelector('.btn').classList.add(...)
    ✅ Dobře: const btn = document.querySelector('.btn');
    btn.addEventListener(...)
    btn.classList.add(...)

  • Používejte specifické selektory

  • Čím specifičtější selektor, tím rychlejší výběr:
    ❌ Pomalé: document.querySelector('.btn') - prohledá celý DOM
    ✅ Rychlé: document.querySelector('#header .btn') - omezí scope
    ✅ Nejrychlejší: document.getElementById('header').querySelector('.btn')

  • Volte správnou metodu pro use case

  • Pro ID: getElementById (nejrychlejší)
    Pro jednu třídu: querySelector (dostatečně rychlé)
    Pro více elementů: querySelectorAll
    Pro často se opakující výběry: cache výsledek

  • Ověřujte existenci elementu

  • querySelector vrací null pokud element neexistuje. Vždy ověřte:
    const btn = document.querySelector('.btn');
    if (btn) {
      btn.addEventListener('click', handler);
    }
    Bez tohoto checku dostanete "Cannot read property 'addEventListener' of null" error.

  • Preferujte data-* atributy pro JS hooks

  • Místo CSS tříd pro JavaScript selektory použijte data atributy:
    <button class="btn js-submit"> - mixing styling a funkcionality
    <button class="btn" data-action="submit"> - čisté oddělení
    Selector: document.querySelector('[data-action="submit"]')

Nejčastější otázky o querySelector

Co je querySelector a jak funguje? Rozbalit

querySelector je moderní JavaScript metoda pro výběr HTML elementů z DOM pomocí CSS selektorů. Na rozdíl od starších metod jako getElementById nebo getElementsByClassName můžete použít libovolný CSS selektor – třídy, ID, atributy, pseudotřídy nebo jejich kombinace. querySelector vrací první nalezený element, querySelectorAll vrací NodeList všech matchujících elementů. Syntaxe je jednoduchá: document.querySelector('.button') nebo document.querySelectorAll('div.card > h2').

Jaký je rozdíl mezi querySelector a querySelectorAll? Rozbalit

querySelector vrací jediný element – první, který odpovídá selektoru. Pokud žádný neexistuje, vrací null. querySelectorAll vrací statickou NodeList všech elementů matchujících selektor – i když najde 100 elementů. NodeList se chová podobně jako pole, ale není to Array (nemá metody map, filter), můžete ho ale převést pomocí Array.from() nebo spread operátoru. querySelector je rychlejší, pokud potřebujete jen první element.

Jak se querySelector liší od getElementById a getElementsByClassName? Rozbalit

getElementById je rychlejší pro výběr podle ID, ale méně flexibilní – funguje pouze pro ID. getElementsByClassName vrací živou HTMLCollection (automaticky se aktualizuje při změnách DOM), zatímco querySelectorAll vrací statickou NodeList. querySelector/querySelectorAll jsou univerzální – můžete kombinovat selektory jako .card.active[data-type="featured"], což se starými metodami nejde. Pro výkon: ID = getElementById > querySelector, pro flexibilitu a clean code = querySelector.

Jak vybrat vnořené elementy pomocí querySelector? Rozbalit

querySelector respektuje CSS syntaxi pro descendant a child selektory. Příklady: document.querySelector('.container .item') vybere element s třídou .item uvnitř .container (libovolná úroveň). document.querySelector('.container > .item') vybere přímé dítě (child). document.querySelector('#menu li:first-child') vybere první položku seznamu v menu. Můžete také volat querySelector na elementu: const container = document.querySelector('.container'); const item = container.querySelector('.item');

Je querySelector pomalejší než getElementById? Rozbalit

Ano, getElementById je technicky rychlejší (nativní vyhledávání podle ID), ale rozdíl je zanedbatelný v běžných aplikacích – řádově mikrovteřiny. querySelector musí parsovat CSS selektor a procházet DOM. V praxi: pokud vybíráte element jednou nebo občas, používejte querySelector pro čistší kód. Pokud vybíráte stejný element v loope tisíckrát, použijte getElementById nebo uložte reference do proměnné. V moderním vývoji se preferuje querySelector pro konzistenci a čitelnost, výkon není problém.

Související pojmy