,
Ugyanazok a kezelők, mint korábban, de ezúttal - a merítés szakaszában. Nos, az elfogás működés közbeni megtekintéséhez kattintson a benne lévő elemre
A kezelők felülről lefelé haladva fognak dolgozni: FORM → DIV → P.
A JS kód a következő:
varelems = document.querySelectorAll("form,div,p"); // minden elemre felakasztunk egy kezelőt az elfogás szakaszában (var i = 0; i< elems.length; i++) {
elems[i].addEventListener("click", highlightThis, true);
}
Senki sem zavarja, hogy mindkét szakaszhoz kezelőket rendeljen, például:
varelems = document.querySelectorAll("form,div,p"); for (var i = 0; i< elems.length; i++) {
elems[i].addEventListener("click", highlightThis, true);
elems[i].addEventListener("click", highlightThis, false);
}
Kattintson a belső elemre
Az esemény átadási sorrendjének megtekintéséhez: FORM → DIV → P → P → DIV → FORM legyen. Vegye figyelembe, hogy az elem
Mindkét szakaszon részt vesz.
Eredmények
Amikor egy esemény bekövetkezik, az elem, amelyen az esemény bekövetkezett, esemény.célként lesz megjelölve.
Az esemény először a dokumentumgyökértől az event.target-ig terjed, és közben meghívja az addEventListener(…., true) segítségével biztosított kezelőket.
Az esemény az event.targettől a dokumentum elejéig terjed, miközben meghívja az addEventListener(…., false) által biztosított kezelőket.
Minden kezelő hozzáférhet az esemény tulajdonságaihoz:
Az event.target az a legmélyebb elem, amelyen az esemény ténylegesen megtörtént.
event.currentTarget (=this) az az elem, amelyen a Ebben a pillanatban az önfeldolgozó dolgozott (amihez „elérkezett” az esemény).
event.eventPhase - melyik fázisban lőtt az eseménykezelő (merülés = 1, float = 3).
A bugyborékolás megállítható az event.stopPropagation() metódus meghívásával, de ez nem ajánlott, mivel váratlan célokra szükség lehet az eseményre.
Most áttekintünk néhány speciális dolgot az Event objektummal való munka során, nevezetesen: buborékolást és elfogást, valamint az esemény delegálását.
Esemény bugyborékolása
Képzelje el, hogy több beágyazott blokkja van:
Ha rákattint a legbelső blokkra, az eseményre kattintásra először fordul elő benne, majd aktiválódik a szülőjében, a szülő szülőjében stb., amíg el nem éri azt a címkét test és tovább a címkére html (majd hozzá dokumentum és azelőtt ablak ).
És ez logikus, mert a belső blokkra kattintva egyszerre kattint az összes külsőre.
Lássuk ezt a következő példában: 3 blokkunk van, mindegyikhez egy onclick esemény kapcsolódik:
Kattintson a legbelső piros blokkra - és látni fogja, hogyan fog működni először a piros blokk onclick-je, majd a kék, majd a zöld:
Ezt a viselkedést ún felszínre kerülése események - egy légbuborék alulról való felemelkedésével analógiával. Csakúgy, mint a buborék, úgy tűnik, hogy a belső elemre való kattintásunk a tetejére úszik, és minden alkalommal magasabb blokkokon aktiválódik.
esemény.célpont
Tegyük fel, hogy két elemünk van: egy div és egy p bekezdés, amely ebben a divben található. Kössük onlicket dívává:
Ha erre a div-re kattintunk, egy bekezdéshez ugorhatunk, vagy olyan helyre, ahol ez a bekezdés nem létezik.
Hogyan lehet ez – nézze meg a következő példát: a zöld a div, a kék pedig a bekezdésünk:
Ha a zöld részre kattintunk, akkor a div-re kattintunk, ha pedig a kékre, akkor először a bekezdésen, majd a div-en történik a kattintás. De mivel az onclick kifejezetten a div-hez van csatolva, általában nem vesszük észre a bekezdés jelenlétét.
Néha azonban szeretnénk tudni, hogy a kattintás közvetlenül a div-re vagy annak leszármazott bekezdésére történt-e. Ebben segítségünkre lesz az Event objektum és annak tulajdona. esemény.célpont - pontosan azt az elemet tárolja, amelyben a kattintás történt.
A következő példában mi div , benne fekszik p és benne - span .
Kössük az onclick eseményt a legfelső elemhez (div), és kattintson a különböző elemekre: div, p, span. Használva esemény.célpont lekérni a legalsó elemet, ahol az esemény történt, és megjeleníteni a nevét a tagName segítségével.
Ha például rákattint a spanra, akkor az esemény elkapja a divünket (elvégre az onclick hozzá van csatolva), de esemény.célpont pontosan fog hazudni span :
Kattintson a különböző blokkra - látni fogja az eredményt:
Az emelkedés megszűnése
Tehát már tudja, hogy minden esemény felugrik a legtetejéig (akár html tag majd a dokumentumhoz, majd az ablakhoz). Néha meg kell állítani ezt az emelkedést. Ezt bármely elem megteheti, amelyen keresztül az esemény felbukkan. Ehhez az elem kódjában hívja meg a metódust event.stopPropagation() .
A következő példában a piros blokkra kattintva magától működni fog, majd a kékre és ennyi - a kék blokk megállítja a további emelkedést, és a zöld blokk nem reagál semmilyen módon:
Kattintson a piros blokkra - látni fogja az eredményt:
elmerülés
Az események pezsgése mellett van még merülés (tudományos adatok szerint lehallgatási szakasz ). Ez azt jelenti, hogy az esemény először fentről lefelé halad (elfogó szakasz), eléri elemünket (célstádium), és csak ezután kezd lebegni (buborékoló szakasz).
Eseménykezelőt az elfogás stádiumának figyelembe vételével csak a segítségével akaszthat fel addEventListener . Ehhez van egy harmadik paramétere: ha igaz, akkor az esemény az elfogási szakaszban indul, ha hamis, akkor a buborékolási szakaszban (ez alapértelmezés szerint):
Vargreen = document.getElementById("zöld"); green.addEventListener("click", func, true); funkció(esemény) ( )
A tulajdonság segítségével meghatározható, hogy melyik szakaszban történt egy esemény event.eventPhase . A következő értékeket veheti fel: 1 - elfogási szakasz, 2 - célszakasz, 3 - emelkedési szakasz.
Bevezetés a delegációba
Képzeljünk el egy helyzetet: hagyjuk ul Többekkel li . Minden li-hez a következő esemény kapcsolódik: ha rákattint, a "!" hozzáadódik a végéhez.
Valósítsuk meg a fentieket:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
var li = document.querySelectorAll("#ul li"); //A ciklusban minden li-re felakasztjuk az addSign függvényt: for (var i = 0; i
Kattints a li-re - látni fogod, hogyan kerül a "!" a végére:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Legyen most egy gombunk is, amelyre kattintva egy új kerül az ul. végére li "tétel" szöveggel. Meglepetésben vagyunk: a mellékelt esemény nem fog működni újnak li! Győződjünk meg erről:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Adjunk hozzá li
Kattintson a gombra a li hozzáadásához, majd erre az új li-re - nem reagál:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Adjunk hozzá li
A probléma megoldásához az új li létrehozásakor függesszen rá egy függvényt addSign az addEventListeneren keresztül. Valósítsuk meg ezt:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Adjunk hozzá li var li = document.querySelectorAll("#ul li"); for (var i = 0; i
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Adjunk hozzá li
Van egy másik út is a probléma megkerülésére – az esemény delegálása. Elemezzük.
Rendezvény delegáció
A delegálás lényege a következő: nem minden li-re, hanem a szülőjükre akasztunk fel egy eseményt ul .
Ugyanakkor meg kell őrizni a forgatókönyvünk teljesítményét: ahogy eddig is, a li-re kattintva a "!" felirat kerül a végére. Csak az esemény az új verzióban lesz függesztve az ul:
var ul = document.getElementById("ul"); //Az esemény felfüggesztése ul: ul.addEventListener("click", addSign); függvény addSign() ( )
Hogyan tegyük ezt: mivel az esemény az ul-ra van akasztva, a függvényen belül elkaphatjuk a li-t esemény.célpont . Hadd emlékeztesselek, mi az event.target – pontosan ez a címke, amelyben a kattintás történt, esetünkben az li .
Tehát itt van a megoldás a problémánkra delegálás útján:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
A kód végrehajtásának eredménye:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Ebben az esetben a megoldásunk automatikusan működik akár új li , mert az esemény nem li, hanem ul-ra van kifüggesztve:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Adjunk hozzá li var ul = document.getElementById("ul"); ul.addEventListener("kattintás", addSign); function addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; ) //A gomb megvalósítása új li hozzáadásához: var button = document.getElementById("button"); button.addEventListener("click", addLi); függvény addLi() ( var li = document.createElement("li"); li.innerHTML = "new li"; ul.appendChild(li); )
Kattintson a gombra a li hozzáadásához, majd erre az új li-re - reagál:
1. bekezdés
2. pont
3. pont
4. pont
5. pont
Adjunk hozzá li
A kódunk működik, de nem hibátlan. Elemezzük ezeket a hiányosságokat, és írjunk egy univerzálisabb megoldást.
Általános rendezvény-delegáció
Kódunk hátránya akkor nyilvánul meg, ha a li-ben van néhány beágyazott címke. Esetünkben legyen címkék én :
Ebben az esetben nyomja meg én felkiáltójelet ad hozzá vége i tag , nem címke li , ahogy szeretnénk (ha a dőlt betűn kívül a li-re kattintasz, akkor minden rendben lesz):
bekezdés dőlt betűvel 1
bekezdés dőlt betűvel 2
bekezdés dőlt betűvel 3
bekezdés dőlt betűvel 4
bekezdés dőlt betűvel 5
var ul = document.getElementById("ul"); ul.addEventListener("kattintás", addSign); függvény addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; )
Kattintson a dőlt betűre - látni fogja, hogyan "!" bekerül a végére (a dőlt betűn kívüli megnyomás jól működik):
A probléma megoldása a következőképpen történik (nem a leírt módszer az egyetlen, hanem a legegyszerűbb): a legközelebbi metódussal megtaláljuk a legközelebbi li-t, amely az event.target szülője, így: event.target.closest("li") .
Hogyan működik: ha a kattintás be volt kapcsolva én , majd be esemény.célpont ebben hazudok, és benne event.target.closest("li") - mi li amiért az eseménynek tüzelnie kell.
Ha a kattintás a li , majd be esemény.célpont , és be event.target.closest("li") a mi li hazudni fog.
Nézzük meg:
bekezdés dőlt betűvel 1
bekezdés dőlt betűvel 2
bekezdés dőlt betűvel 3
bekezdés dőlt betűvel 4
bekezdés dőlt betűvel 5
var ul = document.getElementById("ul"); ul.addEventListener("click", function(event) ( var li = event.target.closest("li"); if (li) ( //ellenőrizd, hogy nincs-e egyáltalán szülő li li.innerHTML = li.innerHTML + "!"; ) ));
A kód végrehajtásának eredménye:
Nem számít, milyen mély a beágyazás: tag én címkében lehet b , és a címkében található span és csak azután be li - mindegy: építkezés event.target.closest("li") bármely fészkelő szintről megtalálja a szülőt.
Amikor egy esemény bekövetkezik, a kezelők először magát a beágyazott elemet aktiválják, majd a szülőt, majd a fölé, és így tovább, felfelé a beágyazott láncon.
Például 3 beágyazott elem van: FORM > DIV > P , mindegyikhez egy kezelő tartozik:
A kód:
A buborékolás biztosítja, hogy egy kattanás a belső
Először az onclick kezelőt hívja meg (ha van ilyen).
Ezért ha a fenti példában a P-re kattint, akkor a figyelmeztetés sorban jelenik meg: p → div → form.
Ezt a folyamatot buborékolásnak nevezik, mert az események a belső elemből felfelé bugyborékolnak a szülőkön keresztül, hasonlóan, mint egy légbuborék a vízben.
esemény.célpont
Bármelyik elemen is elkapjuk az eseményt, mindig megtudhatja, hogy pontosan hol történt. Az eseményt elindító legmélyebb elemet "cél" vagy "forrás" elemnek nevezik, és event.target néven érhető el.
Különbségek ettől (=event.currentTarget):
Az event.target az a forráselem, amelyen az esemény bekövetkezett, ez változatlan a buborékolási folyamat során.
ez az az aktuális elem, amit a buborékolás elért, a kezelő éppen végrehajtja rajta.
Például, ha csak egy form.onclick kezelő van, akkor "elfog" minden kattintást az űrlapon belül. Ahol van egy kattanás belül – felugrik az elemhez
Div (margó-alsó: 10 képpont; )
Most egy kis JavaScript – itt egy nagyon egyszerű ellenőrzést valósítunk meg egy onsubmit eseménykezelőn belül (a küldési esemény elküldésekor elindul egy űrlapon), amely megvizsgálja, hogy a szövegmezők üresek-e. Ha igen, akkor meghívjuk a preventDefault() függvényt az eseményobjektumban – amely leállítja az űrlap elküldését –, majd hibaüzenetet jelenítünk meg az űrlapunk alatti bekezdésben, hogy elmondjuk a felhasználónak, hogy mi a hiba:
Const form = document.querySelector("form"); const fname = document.getElementById("fname"); const lname = document.getElementById("lname"); const para = document.querySelector("p"); form.onsubmit = function(e) ( if (fname.value === "" || lname.value === "") ( e.preventDefault(); para.textContent = "Mindkét nevet ki kell töltenie! ";))
Nyilvánvalóan ez elég gyenge űrlapellenőrzés - nem akadályozza meg, hogy a felhasználó például szóközökkel vagy számokkal érvényesítse az űrlapot a mezőkbe -, de például célra ez rendben van. A kimenet a következő:
Esemény bugyborékolása és rögzítése
Az utolsó téma, amivel itt nem fogsz találkozni, de nagyon fájdalmas lehet, ha nem érted. Az eseménybuborékolás és a rögzítés két olyan mechanizmus, amelyek leírják, mi történik, ha két azonos típusú eseménykezelőt aktiválnak egy elemen. Nézzünk egy példát, hogy ezt megkönnyítsük – nyissa meg a show-video-box.html példát egy új lapon (és egy másik lapon a példát). Az alábbiakban élőben is elérhető:
Rejtett videó példa
Videódoboz-példa megjelenítése
Videó megjelenítése
Ez egy nagyon egyszerű példa, amely megmutatja és elrejti a ) az áramlási tartalom általános tárolóját. Nincs hatással a tartalomra vagy az elrendezésre, amíg a CSS használatával nem stílusos.">
a ) segítségével egy videólejátszást támogató médialejátszót ágyaz be a dokumentumba. Te tudod használni
hangtartalomhoz is, de a elem megfelelőbb felhasználói élményt nyújthat."> benne lévő elem:
Videó megjelenítése
Az Ön böngészője nem támogatja a HTML5 videót. Itt van helyette a videó linkje.
jegyzet : Miért kell foglalkozni a rögzítéssel és a buborékolással is? Nos, a régi rossz időkben, amikor a böngészők sokkal kevésbé voltak kompatibilisek, mint most, a Netscape csak eseményrögzítést, az Internet Explorer pedig csak az események buborékolását használta. Amikor a W3C úgy döntött, hogy megpróbálja szabványosítani a viselkedést és konszenzusra jutni, végül erre a rendszerre jutottak, amely mindkettőt magában foglalta, és ezt a modern böngészők megvalósítják.
jegyzet : Ahogy fentebb említettük, alapértelmezés szerint minden eseménykezelő a buborékolási fázisban van regisztrálva, és ez legtöbbször értelmesebb. Ha valóban szeretne regisztrálni egy eseményt a rögzítési fázisban, akkor ezt úgy teheti meg, hogy regisztrálja a kezelőt az addEventListener() segítségével, és az opcionális harmadik tulajdonságot true értékre állítja.
rendezvény delegációja
A buborékolás azt is lehetővé teszi számunkra, hogy kihasználjuk rendezvény delegációja - ez a koncepció azon a tényen alapul, hogy ha azt szeretné, hogy valamilyen kód lefusson, amikor a nagyszámú gyermekelem bármelyikére kattint, akkor beállíthatja az eseményfigyelőt a szülőre, és a rajtuk megtörtént események a szülőjükhöz kerülnek. ahelyett, hogy az eseményfigyelőt minden gyermekre külön-külön kell beállítani. Emlékszel korábban, hogy azt mondtuk, hogy a buborékolás azt jelenti, hogy először ellenőrizzük az eseményt elindító elemet az eseménykezelő számára, majd az elem szülőjére stb.
Jó példa erre a listaelemek sorozata – ha azt szeretné, hogy mindegyikük egy üzenetet jelenítsen meg, amikor rákattint, beállíthatja a kattintási eseményfigyelőt a szülőn
, és az események a listaelemekből a következőbe buborékolnak .
Ezt a koncepciót részletesebben David Walsh blogja ismerteti, számos példával – lásd: Hogyan működik a JavaScript-események delegálása?
Következtetés
Most már mindent tudnia kell a webes eseményekről ebben a korai szakaszban. Ahogy fentebb említettük, az események valójában nem részei az alapvető JavaScript-nek – a böngésző webes API-jában vannak meghatározva.