web-dev-qa-db-ja.com

Javascript / DOM:DOMオブジェクトのすべてのイベントを削除する方法は?

ただ質問:オブジェクトのすべてのイベントを完全に削除する方法はありますか? div?

編集:div.addEventListener('click',eventReturner(),false);ごとにイベントを追加しています。

function eventReturner() {
    return function() {
        dosomething();
    };
}

EDIT2:私は働いているが、私の場合には使用できない方法を見つけました:

var returnedFunction;
function addit() {
    var div = document.getElementById('div');
    returnedFunction = eventReturner();
    div.addEventListener('click',returnedFunction,false); //You HAVE to take here a var and not the direct call to eventReturner(), because the function address must be the same, and it would change, if the function was called again.
}
function removeit() {
    var div = document.getElementById('div');
    div.removeEventListener('click',returnedFunction,false);
}
65
Florian Müller

removealleventsの意味がわかりません。特定のタイプのイベントのすべてのハンドラーを削除するか、1つのタイプのすべてのイベントハンドラーを削除しますか?

すべてのイベントハンドラーを削除する

(任意のタイプの)すべてのイベントハンドラーを削除する場合は、 clone 要素を使用して、それをそのクローンに置き換えます。

_var clone = element.cloneNode(true);
_

注:これにより属性と子が保持されますが、DOMプロパティへの変更は保持されません。


特定のタイプの「匿名」イベントハンドラーを削除する

もう1つの方法は、 removeEventListener() を使用することですが、すでに試してみて、機能しなかったと思います。 これがキャッチです

addEventListenerを匿名関数に呼び出すと、毎回新しいリスナーが作成されます。 removeEventListenerを匿名関数に呼び出しても効果はありません。匿名関数は、呼び出されるたびに一意のオブジェクトを作成しますが、それを呼び出すことはできますが、既存のオブジェクトへの参照ではありません。この方法でイベントリスナーを追加する場合は、一度だけ追加され、追加されたオブジェクトが破棄されるまで永続的(削除不可)であることを確認してください。

addEventListenerは関数を返すため、基本的にはeventReturnerに匿名関数を渡します。

これを解決するには2つの方法があります。

  1. 関数を返す関数を使用しないでください。関数を直接使用します。

    _function handler() {
        dosomething();
    }
    
    div.addEventListener('click',handler,false);
    _
  2. 返された関数への参照を格納するaddEventListenerのラッパーを作成し、奇妙なremoveAllEvents関数を作成します。

    _var _eventHandlers = {}; // somewhere global
    
    function addListener(node, event, handler, capture) {
        if(!(node in _eventHandlers)) {
            // _eventHandlers stores references to nodes
            _eventHandlers[node] = {};
        }
        if(!(event in _eventHandlers[node])) {
            // each entry contains another entry for each event type
            _eventHandlers[node][event] = [];
        }
        // capture reference
        _eventHandlers[node][event].Push([handler, capture]);
        node.addEventListener(event, handler, capture);
     }
    
    function removeAllListeners(node, event) {
        if(node in _eventHandlers) {
            var handlers = _eventHandlers[node];
            if(event in handlers) {
                var eventHandlers = handlers[event];
                for(var i = eventHandlers.length; i--;) {
                    var handler = eventHandlers[i];
                    node.removeEventListener(event, handler[0], handler[1]);
                }
            }
        }
    }
    _

    そして、あなたはそれでそれを使うことができます:

    _addListener(div, 'click', eventReturner(), false)
    // and later
    removeListeners(div, 'click')
    _

[〜#〜] demo [〜#〜]

注:コードが長時間実行され、多くの要素を作成および削除する場合、含まれている要素を必ず削除する必要があります__eventHandlers_でそれらを破棄するとき。

81
Felix Kling

イベントリスナー独自の関数remove()を使用します。例えば:

getEventListeners().click.forEach((e)=>{e.remove()})
25
JuanGG

これにより、すべてのリスナーが子から削除されますが、大きなページの場合は遅くなります。簡単に書くことができます。

element.outerHTML = element.outerHTML;
20
pabombs

Corwin.amberが言うように、Webkitと他のWebkitには違いがあります。

Chromeの場合:

getEventListeners(document);

これにより、既存のすべてのイベントリスナーを持つオブジェクトが得られます。

Object 
 click: Array[1]
 closePopups: Array[1]
 keyup: Array[1]
 mouseout: Array[1]
 mouseover: Array[1]
 ...

ここから、削除するリスナーに到達できます。

getEventListeners(document).copy[0].remove();

すべてのイベントリスナー:

for(var eventType in getEventListeners(document)) {
   getEventListeners(document)[eventType].forEach(
      function(o) { o.remove(); }
   ) 
}

Firefoxの場合

Remove関数を含まないリスナーラッパーを使用するため、少し異なります。削除するリスナーを取得する必要があります。

document.removeEventListener("copy", getEventListeners(document).copy[0].listener)

すべてのイベントリスナー:

for(var eventType in getEventListeners(document)) {
  getEventListeners(document)[eventType].forEach(
    function(o) { document.removeEventListener(eventType, o.listener) }
  ) 
}

ニュースWebサイトの迷惑なコピー保護を無効にしようとして、この投稿につまずきました。

楽しい!

9
Jmakuc

あなたが何かをするなら、ブラウザがあなたのためにそれをするかもしれません:

divとその属性をコピーして古いものの前に挿入し、コンテンツを古いものから新しいものに移動して古いものを削除しますか?

0
Mic

答えを完成させるために、Webサイトにアクセスし、生成されたHTMLおよびJavaScriptコードを制御できない場合にイベントを削除する実際の例を次に示します。

迷惑なウェブサイトの中には、ログインフォームにユーザー名をコピーアンドペーストできないものがあります。onpasteイベントがonpaste="return false" HTML属性。この場合、入力フィールドを右クリックし、Firefoxのようなブラウザーで「Inspect element」を選択し、HTML属性を削除するだけです。

ただし、次のようなJavaScriptを介してイベントが追加された場合:

document.getElementById("lyca_login_mobile_no").onpaste = function(){return false};

JavaScriptを使用してイベントを削除する必要もあります。

document.getElementById("lyca_login_mobile_no").onpaste = null;

私の例では、ID「lyca_login_mobile_no」を使用しました。これは、訪問したWebサイトで使用されているテキスト入力IDであったためです。

イベントを削除する別の方法(すべてのイベントも削除します)は、削除できない匿名関数を使用してイベントを追加するためにaddEventListenerを使用した場合のように、ノードを削除して新しいノードを作成しますremoveEventListenerで。これは、要素を検査し、HTMLコードをコピーし、HTMLコードを削除してから同じ場所にHTMLコードを貼り付けることにより、ブラウザーコンソールから実行することもできます。

JavaScriptを使用して、より高速で自動化することもできます。

var oldNode = document.getElementById("lyca_login_mobile_no");
var newNode = oldNode.cloneNode(true);
oldNode.parentNode.insertBefore(newNode, oldNode);
oldNode.parentNode.removeChild(oldNode);

更新:WebアプリがAngularなどのJavaScriptフレームワークを使用して作成されている場合、以前のソリューションが機能していないか、アプリを破損しているように見えます。貼り付けを許可する別の回避策は、JavaScriptを使用して値を設定することです。

document.getElementById("lyca_login_mobile_no").value = "username";

現時点では、AngularのようなJavaScriptで完全に記述されたアプリを壊すことなく、すべてのフォーム検証および制限イベントを削除する方法があるかどうかはわかりません。

0
baptx

Chromeのみ

Protractorテスト内でEventListenerを削除しようとしており、テスト内のListenerにアクセスできないため、次の方法で単一タイプのすべてのイベントリスナーを削除します。

function(eventType){
    getEventListeners(window).[eventType].forEach(
        function(e){
            window.removeEventListener(eventType, e.listener)
        }
    );
}

以前の回答がそれ以降は機能しない「削除」メソッドを使用していたため、これが誰かの助けになることを願っています。

0
Filipe Melo