JavaScript

最終更新日:
公開日:

レシピ

イベント

設定したイベントリスナーを解除する

設定したイベントリスナーをremoveEventListenerメソッドを使って解除する方法について解説します。

この記事のポイント

  • 解除するには対象、イベントの種類、実行する関数が全て一致する必要がある
  • オプションcaptureを指定しているときは値に気を付ける
  • イベントリスナーに登録したアロー関数、無名関数はremoveEventListenerメソッドでは解除できない

目次

登録したイベントリスナーを解除する

イベントリスナーに登録するときはaddEventListenerメソッドを使用しますが、反対に解除するときはremoveEventListenerメソッドを使います。

次の例では、addEventListenerメソッドを実行した後にremoveEventListenerメソッドを実行してイベントリスナーを解除しています。
(イベントリスナーを登録してすぐ解除するのは実用的なコードではありませんが、解説用としてご了承ください)

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>GRAYCODE JavaScript</title>
  <script>
    window.addEventListener('load', function(){

      // イベントリスナー登録
      document.getElementById("content1").addEventListener('click', sayHello);

      // イベントリスナー解除
      document.getElementById("content1").removeEventListener('click', sayHello);
    });

    function sayHello() {
      alert("Hello");
    }
  </script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

上記のコードを実行するとsection要素に設定されたイベントリスナーは解除されているためクリックしても何も起こりません。
もしイベントリスナーを再度登録したいときは、改めてaddEventListenerメソッドを実行することでイベントリスナーを再登録することができます。

以上のように、イベントリスナーを解除するには便利なremoveEventListenerメソッドですが、使用には以下の3点に注意する必要があります。

  • イベントと関数が一致する必要がある
  • オプション「capture」を指定しているときは値が一致する必要がある
  • 無名関数で登録すると解除できない

以降は、それぞれの注意点について解説していきます。

イベントと関数が一致する必要がある

removeEventListenerメソッドを使用するには、addEventListenerメソッドで指定した「イベントの種類」と「実行する関数」のいずれも一致している必要があります。
以下のコードは例1と例2はイベントリスナーを解除できず、例3のみ成功します。

コード例

// イベントリスナー登録
document.getElementById("content1").addEventListener('click', sayHello);

// 例1:NG イベントの種類が一致しない
document.getElementById("content1").removeEventListener('mouseover', sayHello);

// 例2:NG 関数が一致しない
document.getElementById("content1").removeEventListener('click', sayBye);

// 例3:OK イベントの種類&関数が一致
document.getElementById("content1").removeEventListener('click', sayHello);

オプション「capture」を指定しているときは値が一致する必要がある

addEventListenerメソッドで第3パラメータにオプションcaptureを指定している場合は、removeEventListenerメソッドでイベントリスナーを解除するためには上記の「イベントの種類」と「関数」に加えてオプションの値が一致する必要があります。

以下のコードは例1と例2はいずれもオプションの値が一致しないため解除できず、例3のみ解除することができます。

コード例

// イベントリスナー登録
document.getElementById("content1").addEventListener('mouseenter', sayHello, { capture:true });

// 例1:NG オプションがないため値が一致しない
document.getElementById("content1").removeEventListener('mouseenter', sayHello);

// 例2:NG オプションの値が一致しない
document.getElementById("content1").removeEventListener('mouseenter', sayHello, { capture:false });

// 例3:OK オプションの値が一致
document.getElementById("content1").removeEventListener('mouseenter', sayHello, { capture:true });

その他のオプションの値は一致していなくても解除することができます。
例えば以下のようにaddEventListenerメソッドでオプションにonceを指定していても、例1と例2はいずれも解除することができます。

コード例

// イベントリスナー登録
document.getElementById("content1").addEventListener('mouseenter', sayHello, { once:true });

// 例1:OK オプションを指定しなくてもOK
document.getElementById("content1").removeEventListener('mouseenter', sayHello);

// 例2:OK オプションの値が一致しなくてもOK
document.getElementById("content1").removeEventListener('mouseenter', sayHello, { once:false });

アロー関数、無名関数で登録すると解除できない

addEventListenerメソッドで第2パラメータに実行する内容を特定の関数名ではなくアロー関数、または無名関数で指定している場合は、removeEventListenerメソッドでイベントリスナーを解除することはできません。

イベントリスナーでアロー関数を登録した場合は解除できない

// クリックされたらアロー関数の内容が実行されるように登録
document.getElementById("content1").addEventListener('click', () => {
  console.log('test');
});

// アロー関数は removeEventListenerメソッド では解除できない
document.getElementById("content1").removeEventListener('click', () => {
  console.log('test');
});

続いて、以下のコード例は無名関数をremoveEventListenerメソッドで解除しようとしている例になります。
こちらもうまくいきません。

イベントリスナーで無名関数を登録した場合も解除できない

// クリックされたら無名関数の内容が実行されるように登録
document.getElementById("content1").addEventListener('click', function() {
  console.log('test');
});

// アロー関数は removeEventListenerメソッド では解除できない
document.getElementById("content1").removeEventListener('click', function() {
  console.log('test');
});

そのため、イベントリスナーを解除する可能性がある場合はaddEventListenerメソッドではアロー関数と無名関数は使用を避ける必要があります。

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

コメントありがとうございます!
運営の参考にさせていただきます。