34
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

removeEventListenerの代わりにAbortSignalを使いましょう

Last updated at Posted at 2023-03-09

きっかけ

あまりこの手の初心者向け記事を見かけないので自分のメモも兼ねて書きます。
この記事はほぼ公式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はいつも最新ですからね

34
19
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?