2012-02-12 18 views
109

私がボタンを持っている、と私はそれにいくつかの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つずつ削除する必要がありますか?

+0

http://stackoverflow.com/questions/3222486/remove-all-javascript-event-listeners-of-an-element-and-its-children – Misiur

+28

アップグレードは、フレームワーク/ライブラリ。 :-) – John

+1

@user印象的な、実際にはこの古い質問よりも古くなっている質問を見つけました。ここでの答えはまだjQuery 1.7です。私はこの質問をしてからどれくらいの時間が経過したのか信じられない。 –

答えて

107

私はこれを行うための最速の方法は、ちょうどすべてのイベントリスナーを削除しますた、ノードのクローンを作成することであると思う:

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

ちょうどのすべての子要素でこの意志も明らかイベントリスナーとして、注意が必要問題のノードです。したがって、保持したい場合は、一度に1つずつリスナーを明示的に削除する必要があります。あなたはjQueryのに反対していない場合は

+0

ありがとう!そして、私はあなたのコードをこのように使いました。関数unbind(ele){ele.parentNode.replaceChild(ele.cloneNode(true)、ele);} ' –

+18

@Derek:ノードとサブツリー全体のクローン作成は悪い考えです。これは、 'node.removeEventListener'を持つノードからすべての' EventListener'を削除するよりもずっと遅いです**。さらに、メモリリーク(ノード+サブツリー)が発生し、コースからすべての 'EventListener'がサブツリーから削除されました。'document.body'であなたの関数を使うと、すべてが爆破されます。 – Saxoier

+1

@Saxoier、ありがとうございましたが、このページの 'body'でテストしたところ、魅力的でした。たぶん私は高速なブラウザ(Google Chrome)を使用しています。 –

22

、これは1行で行うことができます

のjQuery 1.7以降

$("#myEl").off() 

jQueryの< 1.7

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

ここです例:

ここでは

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

+0

長すぎる場合はjQueryの代わりにすべてのリスナーを削除するために '$("#myEl ")。unbind();'または '.off()'(1.7+)を実行してください。 –

+11

'off()'または 'unbind()'はjQuery経由でアタッチされたリスナーだけを削除しますか? – davide

+0

.off()でドキュメントを再読み込みするだけで、すべてのパラメータを省略してすべてのイベントバインディングを削除することができます。ただし、.unbind()を使用すると、eventTypeは必須であり、このためには使用できません。 – Duke

5

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

イベントリスナーを削除します一つの要素に:

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

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

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

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

+1

@Max:あなたの編集提案を感謝します。しかし、私はこのコードをES2015に作り直すことは、このケースで正当化されないと考えています。 – user

+0

あなたが使用しているすべての子どもたちを削除するには: element.innerHTML + = ''; –

関連する問題