きっかけ
あまりこの手の初心者向け記事を見かけないので自分のメモも兼ねて書きます。
この記事はほぼ公式docsの焼きまわしなので、はず公式docsを貼ります。下にスクロールしていくと 「中断可能なリスナーの追加」 という項目が見つかるはずです。
なぜremoveEventListenerを使わないのか
まず特定のlistenerをremoveしたい場合、二度手間になる
// わざわざ取り出して定義しないといけない
const fooListener = () => {
// ...
}
document.addEventListener("keydown", fooListener)
document.removeEventListener("keydown", fooListener)
公式docsにも載っているように
リスナーが capture フラグを設定したものと設定しないものの 2 つ登録されている場合、それぞれを別々に取り外す必要があります。キャプチャするリスナーを取り外しても、同じリスナーのキャプチャしないバージョンには影響しませんし、その逆も同様です。
2つ登録されている場合はさらにめんどくさくなります。
AbortSignalを使いましょう
公式docsの例を丸コピしたものになりますが、AbortSignalを第三の引数に渡すと、後からabort()
を呼ぶだけで特定のlistenerを取り除けます。
// 中断可能なリスナーを table に追加
const controller = new AbortController();
const el = document.getElementById("outside");
el.addEventListener("click", modifyText, { signal: controller.signal } );
// t2 の内容を変更する関数
function modifyText() {
const t2 = document.getElementById("t2");
if (t2.firstChild.nodeValue == "three") {
t2.firstChild.nodeValue = "two";
} else {
t2.firstChild.nodeValue = "three";
controller.abort(); // "three" になったらリスナーを削除
}
}
古いブラウザーを対応しなければならない時の注意事項としては
DOM 仕様書の古い版では、 addEventListener() の第 3 引数はキャプチャーを使用するかどうかを示す論理値でした。
まあすごく古いブラウザーではなければ気にすることはありません。
使用例
このままだとただの公式docsの焼き回しになるのでいくつかの例を出します。
たとえばshortcutを作りたいとき、keydownイベントとkeyupイベントを同時にlistenして、同時にremoveしたいはずです。この場合はAbortSignalを使うと有効的です。
const shortcutController = new AbortController();
document.addEventListener(
"keydown",
(evt) => {
// ...
},
{ signal: shortcutController.signal }
);
document.addEventListener(
"keyup",
(evt) => {
// ...
},
{ signal: shortcutController.signal }
);
// ...ここで何かの処理を書く
// 処理が終わったらshortcutController.abortを呼ぶだけで
// 同時に2つのEventListenrをremoveすることができます
shortcutController.abort();
終わりに
やはり記事よりdocsをちゃんと読みましょう
記事は古いものもありますが、docsはいつも最新ですからね