EventTarget.removeEventListener

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

構文

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

引数

type
イベントリスナーを削除するイベントの型を表す文字列。
listener
イベントターゲットから削除するイベントハンドラーの EventListener 関数です。
options 省略可
イベントリスナーに関する特性を指定する、オプションのオブジェクトです。次のオプションが使用できます。
  • capture: この型のイベントが、DOM ツリーで下位にある任意の EventTarget へ発送される前に listener へ発送されることを示す Boolean です。
  • この API は標準化されていません。 mozSystemGroup: XBL または Firefox の chrome で実行するコードに限り有効であり、リスナーがシステムグループに追加されているかを定義する Boolean です。
useCapture 省略可
削除する 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() の定義
廃止 初回定義

ブラウザーの対応

BCD tables only load in the browser

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

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); }
    }
  };
}

関連情報