Jedna obsluha pro celý seznam

Seznam může mít spoustu položek: deset, sto nebo i nové, které do něj váš skript přidá později. Dát každé položce vlastní obsluhu by bylo pracné. Jde to jednodušeji: jednou obsluhou pro celý seznam.

Funguje to proto, že události probublávají nahoru. Kliknutí na položku je zároveň kliknutím na všechno, v čem položka je: na seznam, na body i na celou stránku. Obsluha kliknutí na seznamu se tak spustí, kdykoli někdo klikne na kteroukoli jeho položku, a event.target řekne, na kterou:

<ul id="zvirata">
    <li>Kočka</li>
    <li>Pes</li>
</ul>
const seznamZvirat = document.querySelector("#zvirata");

seznamZvirat.addEventListener("click", function (event) {
    console.log(event.target.textContent);
});

Kliknutí na Pes vypíše Pes. Obsluha je na seznamu, ale event.target je položka, na kterou se kliklo. A funguje to i pro položky, které do seznamu přibudou později, bez jakékoli nové obsluhy.

Má to jeden háček: event.target je ten nejvnitřnější prvek, na který se kliklo. Když jsou v položce další prvky, třeba <li><strong>Kočka</strong>, 3 roky</li>, kliknutí na slovo Kočka vám dá strong, ne li. A kliknutí vedle položek, na samotný seznam, vám dá ul.

Řeší to metoda closest() (anglicky nejbližší). Dáte jí selektor, stejně jako metodě querySelector(). Začne u samotného prvku a postupuje nahoru přes prvky, ve kterých je, dokud nenajde takový, který selektoru odpovídá:

seznamZvirat.addEventListener("click", function (event) {
    const polozka = event.target.closest("li");
    if (polozka === null) {
        return;
    }
    console.log(polozka.textContent);
});

Ať do položky kliknete kamkoli, v polozka bude li. Když se na žádnou položku nekliklo, closest() nic nenajde a vrátí null, a tak obsluha skončí pomocí return. Bez této kontroly by polozka.textContent skončilo chybou TypeError: Cannot read properties of null (reading 'textContent').

Svá data mají položky obvykle v datových atributech, třeba <li data-vek="3">, a obsluha je přečte pomocí polozka.dataset.vek.

Pokyny

Dejte prvku seznamReceptu jednu obsluhu kliknutí. V ní najděte recept, na který se kliklo, pomocí event.target.closest("li"), a když žádný není, obsluhu ukončete. Jinak ukažte v prvku casText dobu z atributu data-minuty receptu: Doba přípravy: 15 minut pro palačinky. Zkuste kliknout na název receptu i na zbytek jeho řádku.

Zvýrazněte recept, na který se kliklo: dejte jeho li třídu vybrany. Zvýrazněný je vždy jen jeden recept, takže si zvýrazněnou položku pamatujte v proměnné let vybranaPolozka = null; mimo obsluhu. Než zvýrazníte novou položku, odeberte třídu té předchozí, pokud už nějaká je (vybranaPolozka není null), a novou si pak do proměnné uložte.

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

Zpět

3/10

Další