web-dev-qa-db-ja.com

要素内のすべてのリスナーを削除する方法は?

ボタンがあり、それにeventlistnersを追加しました:

document.getElementById("btn").addEventListener("click", funcA, false);
document.getElementById("btn").addEventListener("click", funcB, false);
document.getElementById("btn").addEventListener("click", funcC, false);
document.getElementById("btn").addEventListener("blur" , funcD, false);
document.getElementById("btn").addEventListener("focus", funcE, false);

<button id="btn">button</button>

それらを削除するには:

document.getElementById("btn").removeEventListener("click",funcA);

すべてのリスナーを一度に削除したい場合、または関数参照(funcA)がない場合はどうなりますか?それを行う方法はありますか、それとも1つずつ削除する必要がありますか?

166

これを行う最も速い方法は、ノードを複製することで、すべてのイベントリスナーが削除されると思います。

var old_element = document.getElementById("btn");
var new_element = old_element.cloneNode(true);
old_element.parentNode.replaceChild(new_element, old_element);

これは問題のノードのすべての子要素のイベントリスナーもクリアするため、注意してください。それを維持する場合は、リスナーを1つずつ明示的に削除する必要があります。

141
Ben D

Jqueryに反対していない場合、これは1行で実行できます。

jQuery 1.7 +

$("#myEl").off()

jQuery <1.7

$('#myEl').replaceWith($('#myEl').clone());

以下に例を示します。

http://jsfiddle.net/LkfLezgd/3/

32
Duke

これもcloneNodeに基づいた関数ですが、親ノードのみを複製し、すべての子を移動する(イベントリスナーを保持する)オプションがあります。

function recreateNode(el, withChildren) {
  if (withChildren) {
    el.parentNode.replaceChild(el.cloneNode(true), el);
  }
  else {
    var newEl = el.cloneNode(false);
    while (el.hasChildNodes()) newEl.appendChild(el.firstChild);
    el.parentNode.replaceChild(newEl, el);
  }
}

1つの要素のイベントリスナーを削除します。

recreateNode(document.getElementById("btn"));

要素とそのすべての子のイベントリスナーを削除します。

recreateNode(document.getElementById("list"), true);

オブジェクト自体を保持する必要があるため、cloneNodeを使用できない場合は、 this answer のように、addEventListener関数をラップして、リスナーリストを自分で追跡する必要があります。

9
user