MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Răspândirea evenimentelor

Când apăsăm pe un anumit element pe pagină și se generează un eveniment de apăsare, acest eveniment se poate răspândi de la un element la altul. De exemplu, dacă apăsăm pe un bloc div, de asemenea apăsăm și pe elementul body în care blocul div se află. Adică are loc răspândirea evenimentului.

Există mai multe forme de răspândire a evenimentelor:

  • Ascendente: evenimentul se răspândește în sus prin arborele DOM de la nodurile copil către cele părinte
  • Descendente: evenimentul se răspândește în jos prin arborele DOM de la nodurile părinte către cele copil, până când ajunge la elementul pe care a fost generat evenimentul

Evenimente ascendente

Să considerăm evenimentele ascendente (bubbling), care se răspândesc în sus prin arborele DOM. Să presupunem că avem următoarea pagină web:

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <title>FDC.COM</title>
   <style>
   #blueRect{
       width:100px;
       height:100px;
       background-color:blue;
   }
   #redRect{
       width:50px;
       height:50px;
       background-color:red;
   }
   </style>
</head>
<body>
   <div id="blueRect">
       <div id="redRect"></div>
   </div>
   <script>
   const redRect = document.getElementById("redRect");
   redRect.addEventListener("click", () => console.log("Eveniment pe redRect"));
   
   const blueRect = document.getElementById("blueRect");
   blueRect.addEventListener("click", () => console.log("Eveniment pe blueRect"));
   
   document.body.addEventListener("click", () => console.log("Eveniment pe body"));
   </script>
</body>
</html>

Dacă apăsăm pe div-ul încastrat (roșu), evenimentul va merge către elementul părinte div și apoi către elementul body.

Trebuie să spunem că acest comportament nu este întotdeauna dorit. În acest caz, putem opri răspândirea evenimentului folosind metoda stopPropagation() a obiectului Event:

const redRect = document.getElementById("redRect");
redRect.addEventListener("click", function(e){
   console.log("Eveniment pe redRect");
   e.stopPropagation();
});

Și ca rezultat, evenimentul va fi procesat doar de handlerul pentru redRect.

Adevărul este că stopPropagation() are o problemă - oprește executarea ulterioară a handlerului curent. Totuși, dacă pentru același eveniment al unui element sunt atașate mai multe handlere de evenimente, celelalte handlere vor continua să se execute.

Și pentru a opri de asemenea executarea tuturor celorlalte handlere, putem apela metoda stopImmediatePropagation:

const redRect = document.getElementById("redRect");
function handler1(e){
   console.log("handler1: Eveniment pe redRect");
   e.stopImmediatePropagation();   // oprim de asemenea executarea handler2
}
function handler2(e){
   console.log("handler2: Eveniment pe redRect");
}
redRect.addEventListener("click", handler1);
redRect.addEventListener("click", handler2);

Evenimente descendente

Evenimentele pot fi de asemenea descendente (capturing). Pentru utilizarea lor, în metoda addEventListener() se transmite ca al treilea parametru opțional valoarea logică true sau false.

Valoarea true indică faptul că evenimentul este descendent. În mod implicit, toate evenimentele sunt ascendente.

Luăm aceeași pagină web, doar schimbăm codul JavaScript al acesteia:

const redRect = document.getElementById("redRect");
redRect.addEventListener("click", function(){
   console.log("Eveniment pe redRect");
}, true);

const blueRect = document.getElementById("blueRect");
blueRect.addEventListener("click", function(){
   console.log("Eveniment pe blueRect");
}, true);

document.body.addEventListener("click", function(){
   console.log("Eveniment pe body");
}, true);

Acum evenimentele se vor răspândi în ordine inversă:

← Lecția anterioară Lecția următoare →