Poznajemy ostatnią opcję eventów, jaką jest signal + mamy pierwsze spotkanie z abort controllerem. Do dzieła.

Nasz markup:

<!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>
    <button id="btn">Click me</button>
    <button id="abortBtn">Remove</button>
    <script src="./evtsignal.js" defer></script>
</body>
</html>

Nasz skrypt JS:

let btn = document.querySelector("#btn");
let abortBtn = document.querySelector("#abortBtn");

let controller = new AbortController();

btn.addEventListener("click", function(e){
    alert("btn clicked");
}, {signal: controller.signal});

abortBtn.addEventListener("click", function(e){
    alert("removing event listeners from btn");
    controller.abort();
    this.setAttribute("disabled", true); //e.target.setAttribute("disabled", true)
}, {once: true});

Utworzyliśmy abort controller i przypisaliśmy do eventu poprzez opcję signal. Teraz ta opcja jest w stanie rozłączyć precyzyjnie ten event listener.

Aby udowodnić, że innych nie rozłącza zmodyfikujemy kod:

let btn = document.querySelector("#btn");
let abortBtn = document.querySelector("#abortBtn");

let controller = new AbortController();

btn.addEventListener("click", function(e){
    alert("btn clicked");
}, {signal: controller.signal});

btn.addEventListener("click", function(e){
    alert("btn clicked - this will not be aborted");
});

abortBtn.addEventListener("click", function(e){
    alert("removing event listeners from btn");
    controller.abort();
    this.setAttribute("disabled", true); //e.target.setAttribute("disabled", true)
}, {once: true});

Tylko tamten event zostaje precyzyjnie rozłączony. Więcej eventów niedługo.