A dinamikus webes interakciók rejtett kulcsa

Amikor még tanultam a webfejlesztés köteleit, az egyik meglepő és érdekes viselkedés, amellyel találkoztam, az események bugyborékolása volt. Eleinte szokatlannak tűnt, de ha belegondolunk az események bugyborékolására, látni fogjuk, hogy ennek nagyon sok értelme van. Webfejlesztőként biztosan találkozik az események bugyborékolásával. Tehát mi az esemény bugyborékolása?

Annak érdekében, hogy a felhasználók interakcióba léphessenek weblapokkal, a JavaScript eseményekre támaszkodik. Az esemény olyan eseményekre vagy műveletekre utal, amelyeket az Ön által írt kód észlel, és reagál rájuk. Az események közé tartoznak többek között az egérkattintások, a billentyűlenyomások és az űrlapok beküldése.

A JavaScript eseményfigyelőket használ az események észlelésére és reagálására. Az eseményfigyelő egy olyan funkció, amely egy adott esemény bekövetkezésére figyel vagy vár az oldalon. Például egy kattintási esemény egy gombra. Amikor egy eseményfigyelő észleli az eseményt, amelyre figyel, az eseményhez társított kód végrehajtásával válaszol. Az események rögzítésének és az azokra való reagálásnak ezt a teljes folyamatát eseménykezelésnek nevezik.

Most képzeljük el, hogy három elem van egy oldalon: egy div, egy span és egy gomb. A gombelem a span elembe, a span elem pedig a div elembe van beágyazva. Az alábbiakban ennek illusztrációja látható:

Feltéve, hogy ezeknek az elemeknek mindegyike rendelkezik eseményfigyelővel, amely figyeli a kattintási eseményt, és kattintáskor kinyomtatja a konzolra, mi történik, ha rákattint a gombra?

Ennek teszteléséhez hozzon létre egy mappát, és abban hozzon létre egy index.html nevű HTML-fájlt, egy style.css nevű CSS-fájlt és egy app.js nevű JavaScript-fájlt.

A HTML-fájlban adja hozzá a következő kódot:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Event bubbling</title>
  <link rel="stylesheet" href="https://wilku.top/the-hidden-key-to-dynamic-web-interactions/style.css">
</head>

<body>
  <div>
    <span><button>Click Me!</button></span>
  </div>
  <script src="app.js"></script>
</body>

</html>

A CSS-fájlban adja hozzá a következő kódot a div és a span elem stílusához.

div {
  border: 2px solid black;
  background-color: orange;
  padding: 30px;
  width: 400px;
}

span {
  display: inline-block;
  background-color: cyan;
  height: 100px;
  width: 200px;
  margin: 10px;
  padding: 20px;
  border: 2px solid black;
}

A JavaScript-fájlban adja hozzá a következő kódot, amely eseményfigyelőket ad a div, span és gombelemekhez. Az eseménylistázók mind egy kattintásos eseményt figyelnek.

const div = document.querySelector('div');
div.addEventListener('click', () => {
  console.log("You've clicked a div element")
})

const span = document.querySelector('span');
span.addEventListener('click', () => {
  console.log("You've clicked a span element")
})

const button = document.querySelector('button');
button.addEventListener('click', () => {
  console.log("You've clicked a button")
})

Most nyissa meg a HTML-fájlt egy böngészőben. Tekintse meg az oldalt, majd kattintson az oldalon található gombra. Mit veszel észre? A gombra kattintás eredménye az alábbiakban látható:

A gombra kattintva elindítja az eseményfigyelőt, aki a gombra kattintási eseményt figyel. Azonban a span és div elemek eseményfigyelői is aktiválódnak. Miért van ez így, kérdezheti.

A gombra kattintva elindítja a gombhoz csatolt eseményfigyelőt, amely a konzolra nyomtat. Mivel azonban a gomb egy span elembe van beágyazva, a gombra kattintás azt jelenti, hogy technikailag a span elemre is kattintunk, és ennek következtében az eseményfigyelő aktiválódik.

Mivel a span elem is be van ágyazva a div elembe, a span elemre való kattintás azt is jelenti, hogy a div elemre is kattintunk, és ennek eredményeként annak eseményfigyelője is aktiválódik. Ez az esemény bugyborékolása.

Esemény Buborékolás

Az eseménybuborékolás az a folyamat, amelynek során a HTML-elemek beágyazott halmazában kiváltott esemény továbbterjed, vagy felbuborékol a legbelső elemtől, ahol kiváltották, és felfelé halad a DOM-fán a gyökérelemig, aktiválva az eseményre figyelő összes eseményfigyelőt.

Az eseményfigyelők egy meghatározott sorrendben aktiválódnak, amely megegyezik azzal, ahogyan az esemény buborékol, illetve hogyan terjed a DOM-fában. Tekintsük az alább látható DOM-fát, amely a jelen cikkben használt HTML struktúráját képviseli.

A DOM-fát felbuborékoló kattintási esemény

A DOM-fa egy span-ba ágyazott gombot mutat, amely egy div-be van beágyazva, amely a törzsbe, a törzs pedig a HTML-elembe van beágyazva. Mivel az elemek egymásba vannak ágyazva, amikor rákattint a gombra, a kattintási esemény elindítja a gombhoz csatolt eseményfigyelőt.

Mivel azonban az elemek egymásba vannak ágyazva, az esemény a DOM-fán felfelé (buborék felfelé) a span elemre, majd a div-re, majd a törzsre és végül a HTML elemre kerül, így az összes eseményfigyelő aktiválja a kattintási eseményt. rendelés.

Ezért kerül végrehajtásra a span és div elemekhez csatolt eseményfigyelő. Ha eseményfigyelőink a törzsre és a HTML elemre történő kattintásra figyeltek volna, akkor ők is aktiválódtak volna.

Azt a DOM csomópontot, ahol egy esemény bekövetkezik, célnak nevezzük. Esetünkben, mivel a kattintás a gombon történik, a gombelem az esemény célpontja.

Hogyan lehet megállítani az események bugyborékolását

Annak megakadályozására, hogy egy esemény felbuborékolja a DOM-ot, a stopPropagation() nevű metódust használjuk, amely elérhető az eseményobjektumban. Tekintsük az alábbi kódmintát, amellyel eseményfigyelőt adtunk a gombelemhez.

const button = document.querySelector('button');
button.addEventListener('click', () => {
  console.log("You've clicked a button");
})

A kód egy eseményhez vezet, amely felbuborékolja a DOM-fát, amikor a felhasználó rákattint a gombra. Az események buborékolásának megakadályozása érdekében meghívjuk a stopPropagation() metódust az alábbiak szerint:

const button = document.querySelector('button');
button.addEventListener('click', (e) => {
  console.log("You've clicked a button");
  e.stopPropagation();
})

Az eseménykezelő az a funkció, amely akkor fut le, amikor egy gombra kattintanak. Az eseményfigyelő automatikusan átad egy eseményobjektumot egy eseménykezelőnek. Esetünkben ezt az eseményobjektumot az e változónév reprezentálja, amely paraméterként kerül átadásra az eseménykezelőben.

Ez az eseményobjektum egy eseményről tartalmaz információkat, és hozzáférést biztosít számunkra az eseményekhez kapcsolódó különféle tulajdonságokhoz és módszerekhez. Az egyik ilyen módszer a stopPropagation(), amely az események buborékolásának megakadályozására szolgál. A stopPropagation() meghívása a gomb eseményfigyelőjében megakadályozza, hogy egy esemény felbuborékolja a DOM-fát a gombelemből.

A stopPropagation() metódus hozzáadása után a gombra kattintás eredménye az alábbiakban látható:

A stopPropagation() segítségével megakadályozzuk, hogy egy esemény bugyborékoljon abból az elemből, amelyen használjuk. Például, ha azt szeretnénk, hogy a kattintási esemény a gombelemtől a span elemig buborékoljon, és ne buborékoljon felfelé a DOM-fában, akkor a stopPropagation()-t használjuk az span eseményfigyelőjén.

Eseményrögzítés

Az eseményrögzítés az események buborékolásának az ellentéte. Eseményrögzítéskor egy esemény a legkülső elemről a célelemre csorog le, az alábbi ábra szerint:

Kattintson az eseményrögzítés miatt a célelemre csordogáló eseményre

Például a mi esetünkben, amikor a gombelemre kattintunk, eseményrögzítéskor a div elem eseményfigyelői aktiválódnak először. A span elemen lévő hallgatók követik, és végül a célelemen lévő hallgatók aktiválódnak.

Az eseménybuborékolás azonban az események alapértelmezett terjesztési módja a dokumentumobjektum-modellben (DOM). Az alapértelmezett viselkedés eseménybuborékolásról eseményrögzítésre történő megváltoztatásához egy harmadik argumentumot adunk át eseményfigyelőinknek, hogy az eseményrögzítést igazra állítsák. Ha nem ad át egy harmadik argumentumot az eseményfigyelőknek, az eseményrögzítés hamisra lesz állítva.

Tekintsük az alábbi eseményfigyelőt:

div.addEventListener('click', () => {
  console.log("You've clicked a div element")
})

Mivel nincs harmadik argumentuma, a rögzítés false értékre van állítva. A rögzítés igazra állításához adunk át egy harmadik argumentumot, a true logikai értéket, amely a rögzítést igazra állítja.

div.addEventListener('click', () => {
  console.log("You've clicked a div element")
}, true)

Alternatív megoldásként átadhat egy objektumot, amely a rögzítést igazra állítja, az alábbiak szerint:

div.addEventListener('click', () => {
  console.log("You've clicked a div element")
}, {capture: true})

Az eseményrögzítés teszteléséhez a JavaScript-fájlban adjon hozzá egy harmadik argumentumot az összes eseményfigyelőhöz, az alábbi módon:

const div = document.querySelector('div');
div.addEventListener('click', () => {
  console.log("You've clicked a div element")
}, true)

const span = document.querySelector('span');
span.addEventListener('click', (e) => {
  console.log("You've clicked a span element")
}, true)

const button = document.querySelector('button');
button.addEventListener('click', () => {
  console.log("You've clicked a button");
}, true)

Most nyissa meg a böngészőt, és kattintson a gomb elemre. Ilyen kimenetet kell kapnia:

Figyeljük meg, hogy az eseménybuborékolástól eltérően, ahol a gomb kimenetét nyomtatták ki először, az eseményrögzítésnél az első kimenet a legkülső elemből, a div-ből származik.

Az események buborékolása és az eseményrögzítés az események DOM-ban történő terjesztésének fő módjai. Azonban az események buborékolása az, amit általában az események terjesztésére használnak.

Rendezvény delegáció

Az esemény-delegálás egy olyan tervezési minta, amelyben egyetlen eseményfigyelő egy közös szülőelemhez, például egy

    elemhez van csatolva, ahelyett, hogy az egyes utódelemeken eseményfigyelők lennének. A gyermekelemeken lévő események ezután a szülőelemig buborékolnak, ahol azokat a szülőelem eseménykezelője kezeli.

    Ezért abban az esetben, ha van egy szülő elemünk gyermek elemekkel, csak eseményfigyelőt adunk a szülőelemhez. Ez az eseménykezelő kezeli az összes eseményt a gyermekelemekben.

    Kíváncsi lehet, honnan tudja a szülőelem, hogy melyik gyermekelemre kattintott. Mint korábban említettük, az eseményfigyelő egy eseményobjektumot ad át egy eseménykezelőnek. Ez az eseményobjektum olyan metódusokkal és tulajdonságokkal rendelkezik, amelyek információt nyújtanak egy adott eseményről. Az eseményobjektum egyik tulajdonsága a céltulajdonság. A céltulajdonság arra a konkrét HTML-elemre mutat, ahol egy esemény történt.

    Például, ha van egy rendezetlen listánk listaelemekkel, és eseményfigyelőt csatolunk az

      elemhez, amikor esemény történik egy listaelemen, akkor az eseményobjektumban lévő céltulajdonság arra a konkrét listaelemre fog mutatni, ahol az esemény. történt.

      Az esemény delegálásának működés közbeni megtekintéséhez adja hozzá a következő HTML-kódot a meglévő HTML-fájlhoz:

      <ul>
          <li>Toyota</li>
          <li>Subaru</li>
          <li>Honda</li>
          <li>Hyundai</li>
          <li>Chevrolet</li>
          <li>Kia</li>
        </ul>

      Adja hozzá a következő JavaScript-kódot az esemény delegálásának használatához, hogy egyetlen eseményfigyelőt használjon a szülőelemen az utódelemekben lévő események figyeléséhez:

      const ul = document.querySelector('ul');
      ul.addEventListener('click', (e) => {
        // target element
        targetElement = e.target
        // log out the content of the target element
        console.log(targetElement.textContent)
      })

      Most nyissa meg a böngészőt, és kattintson a lista bármely elemére. Az elem tartalmát az alábbiak szerint kell kinyomtatni a konzolra:

      Egyetlen eseményfigyelő használatával az összes gyermekelemben kezelhetjük az eseményeket. Ha sok eseményfigyelő van egy oldalon, az befolyásolja annak teljesítményét, több memóriát fogyaszt, és az oldalak lassú betöltéséhez és megjelenítéséhez vezet.

      Az esemény delegálása lehetővé teszi, hogy mindezt elkerüljük azáltal, hogy minimálisra csökkentjük az oldalon használandó eseményfigyelők számát. Az esemény delegálása az események buborékolására támaszkodik. Ezért azt mondhatjuk, hogy az eseménybuborékolás segíthet a weboldalak teljesítményének optimalizálásában.

      Tippek a hatékony eseménykezeléshez

      Fejlesztőként, amikor eseményekkel dolgozik a dokumentumobjektum-modellben, fontolja meg az esemény delegálását ahelyett, hogy sok eseményfigyelő legyen az oldal elemein.

      Esemény delegálás használatakor ne felejtsen el eseményfigyelőt csatolni az eseménykezelést igénylő gyermekelemek legközelebbi közös őséhez. Ez segít az események buborékolásának optimalizálásában, és minimalizálja azt az utat is, amelyet az eseménynek meg kell haladnia a kezelés előtt.

      Az események kezelésekor használja az eseményfigyelő által biztosított eseményobjektumot az előnyére. Az eseményobjektum olyan tulajdonságokat tartalmaz, mint például a cél, amelyek hasznosak az események kezelésénél.

      Ha nagyobb teljesítményű webhelyeket szeretne elérni, kerülje a túlzott DOM-manipulációt. A gyakori DOM-manipulációkat kiváltó események negatívan befolyásolhatják webhelye teljesítményét.

      Végül, beágyazott elemek esetén legyen nagyon óvatos, amikor beágyazott eseményfigyelőket csatol az elemekhez. Ez nemcsak a teljesítményt befolyásolhatja, hanem az eseménykezelést nagyon bonyolulttá teszi, és a kódot nehéz lesz karbantartani.

      Következtetés

      Az események a JavaScript hatékony eszközei. Az események buborékolása, az eseményrögzítés és az esemény delegálása fontos eszközök az események JavaScriptben történő kezelésében. Webfejlesztőként a cikk segítségével ismerkedjen meg a koncepciókkal, így interaktívabb, dinamikusabb és hatékonyabb webhelyeket és alkalmazásokat hozhat létre.