Tema
/
Interneto svetainių kliento dalies kūrimas JS

Interaktyvi kortelė — stopPropagation spąstas

Dabar padarom kortelę interaktyvią. Kodo stulpelyje — atnaujintas js/components/card.js: prisideda createFavButton (♡ mygtukas) ir paspaudimas ant visos kortelės, kuris atidaro detalų vaizdą. Pastebėk: kortelė nežino, ką iš tikro reiškia „atidaryti" ar „išsaugoti" — kvietėjas paduoda apdorotojus (onOpen, onToggleFavorite). Tikra būsena ateis 8 pamokoje, tikras maršrutizatorius — 14; komponentui su callback'ais jų nereikia. Šiandien svarbu įvykių jungimas.

Čia ir slypi klasikinis burbuliavimo spąstas. Turim du paspaudimo taikinius, vienas kito viduje:

card.addEventListener('click', () => {
  if (onOpen) onOpen(pic);      // visa kortelė
});

btn.addEventListener('click', (e) => {
  e.stopPropagation();          // ← BE ŠITO ♡ paspaudimas ATIDARO ir detalų vaizdą
  if (onToggleFavorite) onToggleFavorite(pic);
});

Spąstai 1 (stopPropagation). Spusteli ♡. Įvykis suveikia ant mygtuko — bet burbuliuoja iki kortelės, tad suveikia ir kortelės klausytojas. Rezultatas: išsaugai nuotrauką IR atsidaro detalus vaizdas. Vartotojui atrodo, kad ♡ „meta" jį kitur. e.stopPropagation() sustabdo burbuliavimą — kortelės klausytojas nebesuveikia. Klaida tikra ir jos lengva nepastebėti, kol nespustelini būtent ♡.

Spąstai 2 (preventDefault). Formos (nustatymų, kontaktų — 11–12 pamokos) turi tą pačią problemą kitu pavidalu:

form.addEventListener('submit', (e) => {
  e.preventDefault();           // ← BE ŠITO puslapis PERSIKRAUNA ir viską praranda
  handleSubmit();
});

Numatytasis formos submit elgesys — nusiųsti duomenis ir perkrauti puslapį. Vieno puslapio programoje to nenorim niekada: perkrovus dingsta visa būsena. e.preventDefault() sustabdo naršyklės numatytąjį veiksmą, o duomenis tvarkom patys.

Patikrink. Prijunk kortelę su laikinais apdorotojais — createCard(pic, { onOpen: p => console.log('open', p.title), onToggleFavorite: p => console.log('fav', p.title) }) — tada:

1. Spusteli kortelę (ne ♡) → atsidaro detalus vaizdas (arba log'as).
2. Spusteli ♡ → tik išsaugo/pašalina; detalus vaizdas NEATSIDARO.
3. Užkomentuoji e.stopPropagation() → dabar ♡ daro ABU. Grąžini — sutvarkyta.

Spąstai (santrauka). stopPropagation sustabdo įvykio kelionę per DOM (vaikas → tėvas). preventDefault sustabdo naršyklės numatytąjį veiksmą (submit, nuoroda). Skirtingos problemos — nesukeisk jų vietomis.