Skrytý klíč k dynamickým webovým interakcím

Když jsem se ještě učil lana vývoje webu, jedním z překvapivých a fascinujících chování, se kterými jsem se setkal, bylo bublání událostí. Zpočátku to vypadalo nezvykle, ale když se zamyslíte nad událostmi, uvidíte, že to dává smysl. Jako webový vývojář se určitě setkáte s bubláním událostí. Co je tedy bublání událostí?

Aby měl JavaScript uživatelům možnost interagovat s webovými stránkami, spoléhá se na události. Událost odkazuje na výskyty nebo akce, které lze detekovat a reagovat na ně kód, který napíšete. Příklady událostí zahrnují mimo jiné kliknutí myší, stisknutí kláves a odeslání formuláře.

JavaScript používá posluchače událostí k detekci a reakci na události. Posluchač událostí je funkce, která naslouchá nebo čeká na konkrétní událost na stránce. Například událost kliknutí na tlačítko. Když posluchač události zjistí událost, kterou naslouchá, odpoví spuštěním kódu spojeného s událostí. Celý tento proces zachycování a reagování na události se nazývá zpracování událostí.

Nyní si představte, že na stránce máme tři prvky: div, rozpětí a tlačítko. Prvek tlačítka je vnořen do prvku span a prvek span je vnořen do prvku div. Ukázka toho je uvedena níže:

Za předpokladu, že každý z těchto prvků má posluchač události, který naslouchá události kliknutí a po kliknutí se vytiskne do konzoly, co se stane, když kliknete na tlačítko?

Chcete-li to sami vyzkoušet, vytvořte složku a ve složce vytvořte soubor HTML s názvem index.html, soubor CSS s názvem style.css a soubor JavaScript s názvem app.js.

Do souboru HTML přidejte následující kód:

<!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>

V souboru CSS přidejte následující kód pro stylování prvků div a span.

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;
}

Do souboru JavaScript přidejte následující kód, který přidá posluchače událostí do prvků div, span a button. Všichni seznamy událostí poslouchají událost kliknutí.

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")
})

Nyní otevřete soubor HTML v prohlížeči. Prohlédněte si stránku a poté klikněte na tlačítko na stránce. čeho si všimneš? Výsledek kliknutí na tlačítko je zobrazen níže:

Kliknutí na tlačítko spustí posluchač události naslouchající události kliknutí na tlačítko. Spouštějí se však také posluchače událostí na prvcích span a div. Proč tomu tak je, můžete se zeptat.

Kliknutím na tlačítko se spustí posluchač událostí připojený k tlačítku, který se vytiskne na konzoli. Protože je však tlačítko vnořeno do prvku span, kliknutí na tlačítko znamená, že technicky klikneme také na prvek span, a proto se spustí posluchač události.

  Oprava nefunkční SIM karty na Androidu

Protože prvek span je také vnořen do prvku div, kliknutí na prvek span také znamená, že se klikne také na prvek div a v důsledku toho se spustí také posluchač události. Toto je bublání událostí.

Bublající událost

Bublání událostí je proces, při kterém se událost spuštěná ve vnořené sadě prvků HTML šíří nebo probublává z nejvnitřnějšího prvku, kde byla spuštěna, a postupuje po stromě DOM do kořenového prvku, čímž spouští všechny posluchače událostí, kteří na tuto událost naslouchají.

Posluchače událostí jsou spouštěny v určitém pořadí, které odpovídá tomu, jak událost probublává nebo se šíří ve stromu DOM. Zvažte strom DOM zobrazený níže, který představuje strukturu HTML použitého v tomto článku.

Událost kliknutí probublává stromem DOM

Strom DOM zobrazuje tlačítko vnořené do rozpětí, které je vnořeno do prvku div, které je vnořeno do těla a tělo je vnořeno do prvku HTML. Vzhledem k tomu, že prvky byly po kliknutí na tlačítko vnořeny do sebe, událost kliknutí spustí posluchač události připojený k tlačítku.

Protože jsou však prvky vnořené, událost se přesune ve stromu DOM nahoru (bublina nahoru) na prvek span, potom na prvek div, potom na tělo a nakonec na prvek HTML, čímž spustí všechny posluchače události, kteří poslouchají událost kliknutí v tomto prvku. objednat.

To je důvod, proč je spuštěn posluchač událostí připojený k prvkům span a div. Pokud bychom posluchači událostí naslouchali kliknutí na tělo a prvek HTML, byly by také spuštěny.

Uzel DOM, kde dojde k události, se nazývá cíl. V našem případě, protože ke kliknutí dojde na tlačítko, je prvek tlačítka cílem události.

Jak zastavit bublání událostí

Abychom zabránili tomu, aby událost probublávala DOM, používáme metodu nazvanou stopPropagation(), která je k dispozici na objektu události. Zvažte ukázku kódu níže, kterou jsme použili k přidání posluchače události do prvku tlačítka.

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

Kód vede k události, která probublává stromem DOM, když uživatel klikne na tlačítko. Abychom zabránili bublání událostí, zavoláme metodu stopPropagation(), jak je uvedeno níže:

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

Obslužná rutina události je funkce, která se provede po kliknutí na tlačítko. Posluchač události automaticky předá objekt události obsluze události. V našem případě je tento objekt události reprezentován proměnnou jménem e, která se předává jako parametr v obsluze události.

Tento objekt události,e, obsahuje informace o události a také nám poskytuje přístup k řadě vlastností a metod souvisejících s událostmi. Jednou z takových metod je stopPropagation(), která se používá k zabránění bublání událostí. Volání stopPropagation() v posluchači událostí tlačítka zabrání tomu, aby událost probublávala strom DOM z prvku button.

  10 platforem Python Linter pro vyčištění vašeho kódu

Výsledek kliknutí na tlačítko po přidání metody stopPropagation() je uveden níže:

StopPropagation() používáme, abychom zabránili tomu, aby událost vybublala z prvku, na kterém ji používáme. Pokud bychom například chtěli, aby událost click probublávala od prvku button nahoru k prvku span a nebublala dále ve stromu DOM, použili bychom stopPropagation() na posluchači události span.

Zachycení události

Zachycování událostí je opakem bublání událostí. Při zachycování události událost stéká z nejvzdálenějšího prvku do cílového prvku, jak je znázorněno níže:

Klikněte na událost stékající dolů k cílovému prvku kvůli zachycení události

Například v našem případě, když při zachytávání události kliknete na prvek tlačítka, budou posluchači událostí na prvku div první, kdo bude spuštěn. Následují posluchači na prvku span a nakonec budou spuštěni posluchači na cílovém prvku.

Probublávání událostí je však výchozím způsobem, kterým se události šíří v objektovém modelu dokumentu (DOM). Chcete-li změnit výchozí chování z probublávání událostí na zachycování událostí, předáme našim posluchačům událostí třetí argument, aby bylo zachycování událostí nastaveno na true. Pokud posluchačům událostí nepředáte třetí argument, bude zachycování událostí nastaveno na hodnotu false.

Zvažte níže uvedený posluchač události:

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

Protože nemá žádný třetí argument, zachycování je nastaveno na hodnotu false. Chcete-li nastavit zachycení na true, předáme třetí argument, booleovskou hodnotu true, která nastaví zachycení na true.

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

Případně můžete předat objekt, který nastaví zachycení na true, jak je znázorněno níže:

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

Chcete-li otestovat zachycování událostí, přidejte do souboru JavaScript třetí argument ke všem posluchačům událostí, jak je znázorněno:

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)

Nyní otevřete prohlížeč a klikněte na prvek tlačítka. Měli byste dostat takový výstup:

Všimněte si, že na rozdíl od probublávání událostí, kde byl výstup z tlačítka vytištěn jako první, při zachycení události je první výstup z nejvzdálenějšího prvku, div.

Probublávání událostí a zachycování událostí jsou hlavní způsoby, kterými se události v DOM šíří. K šíření událostí se však běžně používá probublávání událostí.

Delegace akce

Delegování události je návrhový vzor, ​​kde je jeden posluchač události připojen ke společnému nadřazenému prvku, například k prvku

    , namísto toho, aby posluchači událostí měli každý z podřízených prvků. Události na podřízených prvcích pak probublávají do nadřazeného prvku, kde je zpracovává obsluha události nadřazeného prvku.

    Proto v případě, že máme nadřazený prvek s podřízenými prvky, přidáme k nadřazenému prvku pouze posluchač události. Tato obsluha události zpracuje všechny události v podřízených prvcích.

    Možná se ptáte, jak bude nadřazený prvek vědět, na který podřízený prvek bylo kliknuto. Jak bylo zmíněno dříve, posluchač události předá objekt události obsluze události. Tento objekt události má metody a vlastnosti, které nabízejí informace o konkrétní události. Jednou z vlastností v objektu události je vlastnost target. Vlastnost target ukazuje na konkrétní prvek HTML, kde došlo k události.

    Pokud máme například neuspořádaný seznam s položkami seznamu a k prvku

      připojíme posluchač události, když na položce seznamu dojde k události, vlastnost target v objektu události bude ukazovat na konkrétní položku seznamu, kde událost došlo.

      Chcete-li vidět delegování události v akci, přidejte do existujícího souboru HTML následující kód HTML:

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

      Přidejte následující kód JavaScript, chcete-li použít delegování události k použití jednoho posluchače událostí v nadřazeném prvku k naslouchání událostem v podřízených prvcích:

      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)
      })

      Nyní otevřete prohlížeč a klikněte na libovolnou položku v seznamu. Obsah prvku by měl být vytištěn na konzole, jak je znázorněno níže:

      Pomocí jediného posluchače událostí můžeme zpracovávat události ve všech podřízených prvcích. To, že je na stránce tolik posluchačů událostí, ovlivňuje její výkon, spotřebovává více paměti a vede k pomalému načítání a vykreslování stránek.

      Delegování událostí nám umožňuje se tomu všemu vyhnout minimalizací počtu posluchačů událostí, které musíme na stránce používat. Delegování událostí závisí na bublání událostí. Můžeme tedy říci, že probublávání událostí může pomoci při optimalizaci výkonu webových stránek.

      Tipy pro efektivní zpracování událostí

      Jako vývojář při práci s událostmi v objektovém modelu dokumentu zvažte použití delegování událostí místo toho, abyste na prvcích na stránce měli mnoho posluchačů událostí.

      Při použití delegování událostí nezapomeňte připojit posluchač události k nejbližšímu společnému předkovi podřízených prvků, které potřebují zpracování událostí. To pomáhá při optimalizaci probublávání událostí a také minimalizuje cestu, kterou musí událost urazit, než je zpracována.

      Při zpracovávání událostí používejte objekt události, který poskytuje posluchač událostí ve svůj prospěch. Objekt události obsahuje vlastnosti, jako je cíl, které se hodí při zpracování událostí.

      Chcete-li mít výkonnější webové stránky, vyhněte se nadměrné manipulaci s DOM. Události, které spouštějí časté manipulace s DOM, mohou negativně ovlivnit výkon vašeho webu.

      A konečně, v případě vnořených prvků buďte velmi opatrní při připojování vnořených posluchačů událostí k prvkům. To může nejen ovlivnit výkon, ale také bude zpracování událostí velmi složité a váš kód bude obtížně udržovatelný.

      Závěr

      Události jsou v JavaScriptu mocným nástrojem. Probublávání událostí, zachycování událostí a delegování událostí jsou důležité nástroje při zpracování událostí v JavaScriptu. Jako webový vývojář se pomocí tohoto článku seznamte s koncepty, abyste mohli vytvářet interaktivnější, dynamičtější a výkonnější weby a aplikace.