ugrás a tartalomhoz

event listener class-ra

mind1 valami név · 2023. Már. 22. (Sze), 18.41
Ugye jól sejtem, hogy ha azt akarom, hogy kapjak egy szép popup ablakot, mikor az egeret egy adott típusú elem fölé viszem, akkor ehhez végig kell mászni a getElementsByClassName eredményén és egyesével hozzá kell adni mindhez ezt a listenert?
Olyan nincs, hogy "add hozzá mindenhez, ami x osztályba tartozik!"?
 
1

window

Endyl · 2023. Már. 23. (Cs), 17.17
Event capturing és bubbling a kulcsszavak. Hozzáadhatod mondjuk a windowhoz (vagy ha tudod, akkor valami közelebbi közös szülőhöz) egyszer a listenert, és utána az event.target alapján teszteled, hogy a számodra megfelelő elemmel (vagy annak gyerekével/szülőjével) történt-e. (Érdemes ellenőrizni, hogy az adott eseménynek van-e capturing/bubbling fázisa. Ha nincs, akkor tényleg csak az adott elemekre teheted egyesével. Általában van bubble fázis.)
2

Kösz.

mind1 valami név · 2023. Már. 23. (Cs), 20.39
Kösz.
4

Olvasmányaim közt megint

mind1 valami név · 2023. Ápr. 13. (Cs), 10.48
Olvasmányaim közt megint felbukkant ez a bubbling és eszembe jutott ez a válaszod.
Biztos, hogy nem értetted félre a kérdésem?
A bubbling értelmezése szerintem:
Történik egy esemény (pl. Click), akkor a cursor pozícióján látszó/elhelyezett elemek eseménykezelői sorban megkapják az eseményt, belülről kifelé.

Én meg itt arra lettem volna kíváncsi, hogy ha van rengeteg azonos osztályba tartozó, egy szinten lévő elem, mondjuk egy fórum/chat oldal egyes kommentjeit magába foglaló div, akkor osztály alapján lehet-e ráhúzni ezekre közös listenert vagy nem úszom meg a
for(const c of document.querySelector(".commentclass"))c.addListener(...); 
futtatását?
Ez csak annyiból volt érdekes, mert eredetileg egy firefox extensiont akartam írni egy fórumhoz, ahol esetenként iszonyat lassan tölt be egy-egy hosszú oldal, ha erre még rátolok egy ilyet, akkor a potenciális userek kivágják a bővítményem. :)
5

Erre jó a capturing/bubbling

Endyl · 2023. Ápr. 13. (Cs), 11.14
Ha van capturing fázis, akkor az esemény lemegy a window-tól, vagy a documentElement-től a dokumentumfán egészen az elemig, ami kiváltotta az eseményt. Ha van bármelyik objektumon vonatkozó eseménykezelő, az meghívódik. Utána a target fázisban (ami mindig van) meghívódnak a kiváltó elemen regisztrált vonatkozó eseménykezelők. Végül ha van bubbling fázis, akkor felmegy az esemény az összes szülő elemen, és meghívódnak a vonatkozó eseménykezelők.

Például az összes click eseményt elvileg tudod egy darab, a window-ra tett eseménykezelővel kezelni (az más kérdés, hogy érdemes-e).
<div class="thread">
	<div class="commentClass"></div>
	<div class="commentClass"></div>
	<div class="commentClass"></div>
	<div class="commentClass"></div>
	<div class="commentClass"></div>
	<div class="commentClass"></div>
	<div class="commentClass"></div>
	<div class="commentClass"></div>
	<div class="commentClass"></div>
</div>
<script>
	window.addEventListener('click', function (e) {
		if (e.target.classList.contains('commentClass')) {
			doWhateverWithTheComment(e.target);
			// ha kell valamelyik, akkor:
			// - e.preventDefault()
			// - e.stopPropagation()
			// - e.stopImmediatePropagation()
			return;
		}
	});
</script>
Persze tesztelésnél nem biztos, hogy csak az event.target-et kell vizsgálni. Hasznos lehet még a matches(), closest(), querySelector[All](), stb. függvények.
6

Ja, így azt hiszem, értem,

mind1 valami név · 2023. Ápr. 14. (P), 07.58
Ja, így azt hiszem, értem, mire gondoltál.
Utoljára valahova oda lyukadtam ki, hogy minden elem, amivel foglalkozni akarok, kapjon listenert és azon belül a currenttarget-re hivatkozom, amikor a kattintott elemmel akarok csinálni valamit.

Ui: átírtam kicsit. A "minden div..." helyett "minden elem, amivel foglalkozni akarok..."
8

matches vs classList

mind1 valami név · 2023. Ápr. 14. (P), 09.31
Van érdemi különbség a
event.currentTarget.matches(".commentClass")
és a
event.currentTarget.classList.contains("commentClass")
között?
Már azon túl, hogy az első a kulturált verzió.
Egy tippem van: egy vscode jellegű IDE az elsőnél talán be tud segíteni, ha ismeri a használt HTML-t, hogy jó nevet írjak bele. (bár ez csak feltételezés, de okozott már pár meglepetést JS-ben :) )
9

Egyformán kulturáltak :)

Endyl · 2023. Ápr. 14. (P), 11.12
Egyformán kulturáltak :) csak a matches többet tud. Ha csak az érdekel, hogy a targetnek van-e adott osztálya, akkor a classListet használnám. De a matches-zel tudsz bármilyen selectorra tesztelni, pl. hogy egy adott selectorra passzoló elemen belül történt-e az esemény:
event.target.matches('.commentClass *')
Persze ezt éppen ki lehet váltani egy ilyennel is:
event.target.closest('.commentClass')
Bár nem mértem, és valszeg nem is számít a legtöbb esetben, amíg nagyobb dolgok nincsenek optimalizálva, de azt gondolnám, hogy a classList.contains() hívása olcsóbb lehet.
7

Végső soron a for szerkezet

mind1 valami név · 2023. Ápr. 14. (P), 09.23
Végső soron a for szerkezet kikerülhető, bár performancia tekintetében nem lesz sokkal jobb:
document.querySelectorAll(".commentClass").forEach((elem) => elem.addEventListener(...))
Logikailag ugyanaz, amit szerettem volna kikerülni, viszont leírva azért sokkal szebb így, mint hagyományos for ciklussal :)
3

Mellékszál...

mind1 valami név · 2023. Már. 24. (P), 15.52
Na ezért nem voltam és nem is leszek soha programozó.
Kezdődött az egész azzal, hogy JS tanulás.
De akkor újra kell html és css is.
De akkor kell valami komfortosabb tesztkörnyezet, írok egy kis webes akármit python+flask. De ehhez elő kell szedni a vonatkozó tutorialokat, mert sok dolgot elfelejtettem.
Na jó, akkor ki kell próbálni, hogy ez hogy megy, az hogy megy...

Ahelyett, hogy leírnám, hogy mit csináljon és azt lekódolnám.
És folyton elkalandozok az eredeti témától.
A fenti kérdés is azért merült fel, mert végre megvan a webes app, ami megmutatja a könyvtárak tartalmát (nginx fancyindex vagy mi a ... egyébként, ha nem akarom megírni :) ), de jó lenne, ha egy jobb klikkre megmutatná a fájl paramétereit. (Félig megvan, csak lusta vagyok tisztességesen megírni)