Kolejna szybka lekcja, poznajemy eventy w JavaScript. Kontynuacja lekcji poprzednich, do dzieła!

Ok, markup ten sam:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="myDiv">
        Text node in div
        <ul id="myUl">
            Text node in ul
            <li>Click Me</li>
            <li>Click Me</li>
            <li>Click Me</li>
        </ul>
    </div>
    <script src="./evtphase.js" defer></script>
</body>
</html>

JS zmieniony – eventom z capture dodajemy once na true:

let div = document.querySelector("#myDiv");
let ul = document.querySelector("#myUl");
let liFirst = ul.querySelector("li");


liFirst.addEventListener("click", function(e){
    console.log(e.target);
    alert("li clicked - target phase");
    
});

ul.addEventListener("click", function(e){
    console.log(e.target);
    alert("ul clicked - capture/target phase");
   
}, {capture: true, once:true});

ul.addEventListener("click", function(e){
    alert("Ul clicked - bubble/target phase");
});

div.addEventListener("click", function(e){
    console.log(e.target);
    alert("div clicked - capture/target phase");
    
}, {capture: true, once:true});

div.addEventListener("click", function(e){
    alert("div clicked - bubble/target phase");
});

Za pierwszym razem nic się nie zmieni, za drugim te eventy już nie będą odpalane. Mogą się tylko raz odpalić i koniec.

Propagację w górę też możemy zatrzymać:

liFirst.addEventListener("click", function(e){
    e.stopPropagation();
    console.log(e.target);
    alert("li clicked - target phase");
    
});

Czyli tak:

  • capture true oznacza, że jeżeli event nie jest tknięty bezpośrednio (target i currentTarget to to samo) tylko pośrednio, przez dziecko, to odpali się przed tym dzieckiem, w caputre phase
  • once true oznacza, że event (niezależnie od tego co go uruchomiło) ma prawo odpalić się raz
  • stopPropagation oznacza, że dziecko nie odpala eventów swoich rodziców, nie propaguje w górę (no chyba że się odpaliły w capture phase), te eventy natomiast można odpalić dalej bezpośrednio klikając rodzica

Teraz passive. Passive oznacza, że w evencie nie będziemy używać event.preventDefault, które już znamy. Mamy też signal, o nim niedługo.