EventTarget.removeEventListener

  • Revision slug: Web/API/EventTarget.removeEventListener
  • Revision title: EventTarget.removeEventListener
  • Revision id: 475207
  • Created:
  • Creator: kscarfone
  • Is current revision? No
  • Comment Updated tags

Revision Content

Removes the event listener previously registered with {{domxref("EventTarget.addEventListener")}}.

Syntax

target.removeEventListener(type, listener[, useCapture])
type
A string representing the event type being removed.
listener
The listener parameter indicates the {{ domxref("EventListener") }} function to be removed.
useCapture {{ optional_inline() }}
Specifies whether the {{ domxref("EventListener") }} being removed was registered as a capturing listener or not. If not specified, useCapture defaults to false.
If a listener was registered twice, one with capture and one without, each must be removed separately. Removal of a capturing listener does not affect a non-capturing version of the same listener, and vice versa.
Note: useCapture became optional only in more recent versions of the major browsers; for example, it was not optional prior to Firefox 6. You should provide that parameter for broadest compatibility.

Notes

If an {{ domxref("EventListener") }} is removed from an {{ domxref("EventTarget") }} while it is processing an event, it will not be triggered by the current actions. An {{ domxref("EventListener") }} can never be invoked after being removed.

Calling removeEventListener() with arguments which do not identify any currently registered {{ domxref("EventListener") }} on the EventTarget has no effect.

Example

This is an example of adding and then removing an event listener.

var div = document.getElementById('div');
var listener = function (event) {
  /* do something here */
};
div.addEventListener('click', listener, false);
div.removeEventListener('click', listener, false);

Browser compatibility

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 1.0 {{ CompatGeckoDesktop("1") }} 9.0 7 1.0
useCapture made optional  {{ CompatVersionUnknown() }} 6.0 9.0 (12.00)  {{ CompatVersionUnknown() }}
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 1.0 {{ CompatGeckoMobile("1") }} 9.0 6.0 1.0

Gecko notes

  • Prior to Firefox 6, the browser would throw if the useCapture parameter was not explicitly false. Prior to Gecko 9.0 {{ geckoRelease("9.0") }}, addEventListener() would throw an exception if the listener parameter was null; now the method returns without error, but without doing anything.

Opera notes

  • Opera 12.00 will make the useCapture parameter optional (source)

WebKit notes

  • Although WebKit has explicitly added [optional] to the useCapture parameter fairly recently, it had been working before the change. The new change landed in Safari 5.1 and Chrome 13.

See also

{{ domxref("EventTarget.addEventListener()") }}.

Specification

Polyfill to support older browsers

addEventListener() and removeEventListener() are not present in older browsers. You can work around this by inserting the following code at the beginning of your scripts, allowing use of addEventListener() and removeEventListener() in implementations which do not natively support it.

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

 

{{ languages( { "fr": "fr/DOM/element.removeEventListener", "ja": "ja/DOM/element.removeEventListener", "pl": "pl/DOM/element.removeEventListener" } ) }}

Revision Source

<p>Removes the event listener previously registered with {{domxref("EventTarget.addEventListener")}}.</p>
<h2 id="Syntax" name="Syntax">Syntax</h2>
<pre class="syntaxbox">
<em>target</em>.removeEventListener(<em>type</em>, <em>listener</em>[, <em>useCapture</em>])</pre>
<dl>
  <dt>
    <code>type</code></dt>
  <dd>
    A string representing the event type being removed.</dd>
  <dt>
    <code>listener</code></dt>
  <dd>
    The <code>listener </code>parameter indicates the {{ domxref("EventListener") }} function to be removed.</dd>
  <dt>
    <code>useCapture</code> {{ optional_inline() }}</dt>
  <dd>
    Specifies whether the {{ domxref("EventListener") }} being removed was registered as a capturing listener or not. If not specified, <code>useCapture</code> defaults to <code>false</code>.</dd>
  <dd>
    If a listener was registered twice, one with capture and one without, each must be removed separately. Removal of a capturing listener does not affect a non-capturing version of the same listener, and vice versa.</dd>
</dl>
<div class="note">
  <strong>Note:</strong> <code>useCapture</code> became optional only in more recent versions of the major browsers; for example, it was not optional prior to Firefox 6. You should provide that parameter for broadest compatibility.</div>
<h2 id="Compatibility" name="Compatibility">Notes</h2>
<p>If an {{ domxref("EventListener") }} is removed from an {{ domxref("EventTarget") }} while it is processing an event, it will not be triggered by the current actions. An {{ domxref("EventListener") }} can never be invoked after being removed.</p>
<p>Calling <code>removeEventListener()</code> with arguments which do not identify any currently registered {{ domxref("EventListener") }} on the EventTarget has no effect.</p>
<h2 id="Example">Example</h2>
<p>This is an example of adding and then removing an event listener.</p>
<pre class="brush: js">
var div = document.getElementById('div');
var listener = function (event) {
  /* do something here */
};
div.addEventListener('click', listener, false);
div.removeEventListener('click', listener, false);
</pre>
<h2 id="Browser_Compatibility" name="Browser_Compatibility">Browser compatibility</h2>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Chrome</th>
        <th>Firefox (Gecko)</th>
        <th>Internet Explorer</th>
        <th>Opera</th>
        <th>Safari (WebKit)</th>
      </tr>
      <tr>
        <td>Basic support</td>
        <td>1.0</td>
        <td>{{ CompatGeckoDesktop("1") }}</td>
        <td>9.0</td>
        <td>7</td>
        <td>1.0</td>
      </tr>
      <tr>
        <td><code>useCapture</code> made optional</td>
        <td>&nbsp;{{ CompatVersionUnknown() }}</td>
        <td>6.0</td>
        <td>9.0</td>
        <td>(12.00)</td>
        <td>&nbsp;{{ CompatVersionUnknown() }}</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="compat-mobile">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Android</th>
        <th>Firefox Mobile (Gecko)</th>
        <th>IE Mobile</th>
        <th>Opera Mobile</th>
        <th>Safari Mobile</th>
      </tr>
      <tr>
        <td>Basic support</td>
        <td>1.0</td>
        <td>{{ CompatGeckoMobile("1") }}</td>
        <td>9.0</td>
        <td>6.0</td>
        <td>1.0</td>
      </tr>
    </tbody>
  </table>
</div>
<h3 id="Gecko_notes">Gecko notes</h3>
<ul>
  <li>Prior to Firefox 6, the browser would throw if the&nbsp;useCapture parameter was not explicitly&nbsp;<font face="'Courier New', 'Andale Mono', monospace"><span style="line-height: normal;">false</span></font>. Prior to Gecko 9.0 {{ geckoRelease("9.0") }}, <code>addEventListener()</code> would throw an exception if the listener parameter was <code>null</code>; now the method returns without error, but without doing anything.</li>
</ul>
<h3 id="Opera_notes">Opera notes</h3>
<ul>
  <li>Opera 12.00 will make the <code>useCapture</code> parameter optional (<a class="external" href="http://my.opera.com/ODIN/blog/2011/09/29/what-s-new-in-opera-development-snapshots-28-september-2011-edition">source</a>)</li>
</ul>
<h3 id="WebKit_notes">WebKit notes</h3>
<ul>
  <li>Although WebKit has explicitly added [optional] to the <code>useCapture</code> parameter <a class="external" href="http://trac.webkit.org/changeset/89781">fairly recently</a>, it had been working before the change. The new change landed in Safari 5.1 and Chrome 13.</li>
</ul>
<h2 id="See_also">See also</h2>
<p>{{ domxref("EventTarget.addEventListener()") }}.</p>
<h3 id="Specification" name="Specification">Specification</h3>
<ul>
  <li><a class="external" href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget-removeEventListener">removeEventListener </a></li>
</ul>
<h2 id="Polyfill_to_support_older_browsers">Polyfill to support older browsers</h2>
<p><code>addEventListener()</code> and <code>removeEventListener()</code> are not present in older browsers. You can work around this by inserting the following code at the beginning of your scripts, allowing use of <code>addEventListener()</code> and <code>removeEventListener()</code> in implementations which do not natively support it.</p>
<pre class="brush: js">
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 &lt; oEvtListeners.aEls.length; iElId++) {
      if (oEvtListeners.aEls[iElId] === this) {
        for (iLstId; iLstId &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; aElListeners.length; iLstId++) {
      if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); }
    }
  };
}
</pre>
<h3 id="Example" name="Example">&nbsp;</h3>
<p>{{ languages( { "fr": "fr/DOM/element.removeEventListener", "ja": "ja/DOM/element.removeEventListener", "pl": "pl/DOM/element.removeEventListener" } ) }}</p>
Revert to this revision