EventTarget.removeEventListener() メソッドは、EventTarget から、以前に EventTarget.addEventListener() で登録されたイベントリスナーを削除します。削除されるイベントリスナーはイベントの型、イベントリスナー関数そのもの、マッチングプロセスに影響を与えるさまざまな任意のオプションを使用して識別します。削除するイベントリスナーのマッチング をご覧ください。

構文

target.removeEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, useCapture]);

引数

type
イベントリスナーを削除するイベントの型を表す文字列。
listener
イベントターゲットから削除するイベントハンドラーの EventListener 関数です。
options Optional
イベントリスナーに関する特性を指定する、オプションのオブジェクトです。以下のオプションを使用できます:
  • capture: この型のイベントが、DOM ツリーで下位にある任意の EventTarget へ発送される前に listener へ発送されることを示す Boolean です。
  • passive: listenerpreventDefault() を呼び出さないことを示す Boolean です。この場合は、ユーザーエージェントはその呼び出しを無視して、コンソールに警告を表示します。
  • mozSystemGroup: XBL または Firefox の chrome で実行するコードに限り有効であり、リスナーがシステムグループに追加されているかを定義する Boolean です。
useCapture Optional
削除する EventListener がキャプチャーリスナーとして登録されているかを指定します。この引数を省略した場合は、既定値の false であるとみなします。
リスナーが 2 回登録されていてひとつはキャプチャー、もうひとつは非キャプチャーである場合は、それぞれを個別に削除します。キャプチャーリスナーを削除しても、同じリスナーの非キャプチャーリスナーには影響がありません。逆も同様です。

戻り値

undefined です。

削除するイベントリスナーのマッチング

addEventListener() を呼び出して以前に追加したイベントリスナーは、最終的に削除が必要な状態になることがあります。removeEventListener() に同じ type および listener の引数を指定しなければならないことは明らかですが、optionsuseCapture の引数はどうでしょうか?

addEventListener() は、オプションが異なっていれば同じ型に対して同じリスナーを複数追加できますが、removeEventListener() が確認するオプションは capture/useCapture フラグだけです。マッチさせるためにこの値は removeEventListener() で一致していなければなりませんが、他の値は一致していなくてもかまいません。

例えば、以下の addEventListener() で考えましょう:

element.addEventListener("mousedown", handleMouseDown, true);

そして、以下 2 つの removeEventListener() の呼び出しについて考えましょう:

element.removeEventListener("mousedown", handleMouseDown, false);     // 失敗
element.removeEventListener("mousedown", handleMouseDown, true);      // 成功

1 番目の呼び出しは、useCapture の値が異なるため失敗します。2 番目は、useCapture が一致しますので成功します。

次に、以下の呼び出しを考えましょう:

element.addEventListener("mousedown", handleMouseDown, { passive: true });

ここでは passivetrue に設定した options を指定していますが、他のオプションは既定値の false のままです。

では、以下の removeEventListener() の呼び出しについて、順番に見ていきましょう。capture または useCapturetrue であるものは失敗して、そのほかは成功します。capture の設定だけが removeEventListener() に関与します。

element.removeEventListener("mousedown", handleMouseDown, { passive: true });     // 成功
element.removeEventListener("mousedown", handleMouseDown, { capture: false });    // 成功
element.removeEventListener("mousedown", handleMouseDown, { capture: true });     // 失敗
element.removeEventListener("mousedown", handleMouseDown, { passive: false });    // 成功
element.removeEventListener("mousedown", handleMouseDown, false);                 // 成功
element.removeEventListener("mousedown", handleMouseDown, true);                  // 失敗

一部のブラウザーはこれとは動作が異なることは注目する価値があり、他に特別な理由がない限り removeEventListener() を呼び出すときは、addEventListener() を呼び出したときと同じ値を使用するとよいでしょう。

注記

EventListener がイベントを処理中である EventTarget から削除された場合、現在のアクションによってそのイベントリスナーが実行されることはありません。EventListener は、決して削除された後に実行されることはありません。ただし、再追加することができます。

EventTarget 上にある現在のどの EventListener も指定していない引数付きの removeEventListener() は、何の効果もありません。

この例は、click ベースのイベントリスナーを追加して mouseover ベースのイベントリスナーを削除する方法を示します。

var body =
        document.querySelector('body'),
    clickTarget =
        document.getElementById('click-target'),
    mouseOverTarget =
        document.getElementById('mouse-over-target'),
    toggle = false;

function makeBackgroundYellow() {
    'use strict';

    if (toggle) {
        body.style.backgroundColor = 'white';
    } else {
        body.style.backgroundColor = 'yellow';
    }

    toggle = !toggle;
}

clickTarget.addEventListener('click',
    makeBackgroundYellow,
    false
);

mouseOverTarget.addEventListener('mouseover', function () {
    'use strict';

    clickTarget.removeEventListener('click',
        makeBackgroundYellow,
        false
    );
});

仕様

仕様書 策定状況 コメント
DOM
EventTarget.removeEventListener() の定義
現行の標準  
DOM4
EventTarget.removeEventListener() の定義
勧告  
Document Object Model (DOM) Level 2 Events Specification
EventTarget.removeEventListener() の定義
勧告 初期定義

ブラウザー実装状況

機能 Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
基本サポート 1.0[1][2] (有) 1.0 (1.7 or earlier)[3] 9.0 7[4] 1.0[1]
useCapture を省略可能 (有) (有) 6.0 9.0 11.60 (有)
options 引数 49.0 未サポート        
機能 Android Android Webview Edge Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Android 版 Chrome
基本サポート 1.0[1] (有)[2] (有) 1.0 (1)[3] 9.0 6.0[4] 1.0[1] (有)[2]
useCapture を省略可能 ? (有) (有)         (有)
options 引数 未サポート 49.0 未サポート         49.0

[1] WebKit で useCapture 引数に "[optional]" を明示的に付加したのは Safari 5.1 および Chrome 13 ですが、その前から動作していました。

[2] Chrome 49 より前は、type および listener 引数が省略可能でした。

[3] Firefox 6 より前は、useCapture 引数が明示的に false ではない場合に例外が発生していました。Gecko 9.0 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6) より前は、listener 引数が null であった場合に addEventListener() で例外が発生しました。現在はエラーは発生しませんが、何も行いません。

[4] Opera 11.60 で useCapture 引数が省略可能になりました (出典)。

[5] 後方互換性のため options をサポートするブラウザーは、第 3 引数で options または Boolean のいずれかを受け入れます。

古いブラウザーをサポートするためのポリフィル

addEventListener() および removeEventListener() は、古いブラウザーで提供されていません。以下のコードをスクリプトの先頭に挿入するとこの問題を回避でき、addEventListener() および removeEventListener() をネイティブにサポートしない実装でもこれらを使用できます。ただし、Element.prototype が Internet Explorer 8 までサポートされていなかったため、この方法は Internet Explorer 7 およびそれ以前では動作しません。

if (!Element.prototype.addEventListener) {
  var oListeners = {};
  function runListeners(oEvent) {
    if (!oEvent) { oEvent = window.event; }
    for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) {
      if (oEvtListeners.aEls[iElId] === this) {
        for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); }
        break;
      }
    }
  }
  Element.prototype.addEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
    if (oListeners.hasOwnProperty(sEventType)) {
      var oEvtListeners = oListeners[sEventType];
      for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
        if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
      }
      if (nElIdx === -1) {
        oEvtListeners.aEls.push(this);
        oEvtListeners.aEvts.push([fListener]);
        this["on" + sEventType] = runListeners;
      } else {
        var aElListeners = oEvtListeners.aEvts[nElIdx];
        if (this["on" + sEventType] !== runListeners) {
          aElListeners.splice(0);
          this["on" + sEventType] = runListeners;
        }
        for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) {
          if (aElListeners[iLstId] === fListener) { return; }
        }     
        aElListeners.push(fListener);
      }
    } else {
      oListeners[sEventType] = { aEls: [this], aEvts: [ [fListener] ] };
      this["on" + sEventType] = runListeners;
    }
  };
  Element.prototype.removeEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
    if (!oListeners.hasOwnProperty(sEventType)) { return; }
    var oEvtListeners = oListeners[sEventType];
    for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
      if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
    }
    if (nElIdx === -1) { return; }
    for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) {
      if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); }
    }
  };
}

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: Dolphin_Wood, yyss, jgs, fscholz, khalid32, ethertank, Potappo
 最終更新者: Dolphin_Wood,