web-dev-qa-db-ja.com

匿名イベントリスナーの削除

とにかく次のように追加されたイベントリスナーを削除しますか?

element.addEventListener(event, function(){/* do work here */}, false);

要素を交換せずに?

48
erikvold

作成時にイベントハンドラーへの参照を保存しない限り、イベントハンドラーを完全に削除する方法はありません。

私は通常、これらをそのページのメインオブジェクトに追加します。その後、そのオブジェクトを使い終わったら、繰り返し処理してきれいに破棄できます。

19
Joe

次のようにイベントリスナーを削除できます:

element.addEventListener("click", function clicked() {
    element.removeEventListener("click", clicked, false);
}, false);
16
icktoofay

匿名boundイベントリスナー

要素のすべてのイベントリスナーを削除する最も簡単な方法は、そのouterHTMLをそれ自体に割り当てることです。これにより、HTMLパーサーを通じてHTMLの文字列表現が送信され、解析されたHTMLが要素に割り当てられます。 JavaScriptが渡されないため、バインドされたイベントリスナーはありません。

_document.getElementById('demo').addEventListener('click', function(){
    alert('Clickrd');
    this.outerHTML = this.outerHTML;
}, false);_
<a id="demo" href="javascript:void(0)">Click Me</a>

匿名委任イベントリスナー

1つの注意点は、委任されたイベントリスナー、または子の一連の基準に一致するすべてのイベントを監視する親要素のイベントリスナーです。これを回避する唯一の方法は、委任されたイベントリスナーの基準を満たさないように要素を変更することです。

_document.body.addEventListener('click', function(e){
    if(e.target.id === 'demo') {
        alert('Clickrd');
        e.target.id = 'omed';
    }
}, false);_
<a id="demo" href="javascript:void(0)">Click Me</a>
10
user4639281

上書きしてみてくださいelement.addEventListenerそしてあなたがやりたいことを何でもします。
何かのようなもの:

var orig = element.addEventListener;

element.addEventListener = function (type, listener) {
    if (/dontwant/.test(listener.toSource())) { // listener has something i dont want
        // do nothing
    } else {
        orig.apply(this, Array.prototype.slice.apply(arguments));
    }
};

pS:それはお勧めできませんが、それはトリックを行います(テストしていません)

4
w35l3y

編集:コメントごとに Manngo が提案されているため、。off()の代わりに。unbind()as。unbind()はjQuery 3.0の時点で非推奨になり、jQuery 1.7以降は置き換えられました。

これは古い質問であり、jQueryについては触れていませんが、これはsearchtermの最初の結果 'jquery remove anonymous event handler'なので、ここに回答を投稿します。

。off() 関数を使用して削除してみることができます。

$('#button1').click(function() {
       alert('This is a test');
});

$('#btnRemoveListener').click(function() {
       $('#button1').off('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button1">Click me</button>
<hr/>
<button id="btnRemoveListener">Remove listener</button>

ただし、これはjQueryを使用してリスナーを追加した場合にのみ機能します- 。addEventListenerではありません

これが見つかりました ここ

3
general64

リテラル関数でのイベントハンドラーの割り当ては注意が必要です。ノードを複製してクローンで置き換えることなく、イベントハンドラーを削除する方法がないだけでなく、同じハンドラーを誤って複数回割り当てることもできます。ハンドラへの参照。 2つの関数は、たとえ文字が同一であっても、常に2つの異なるオブジェクトとして扱われます。

2
kennebec

古い質問ですが、これが解決策です。

厳密に言えば、関数への参照を保存しない限り、匿名イベントリスナーを削除することはできません。無名関数を使用する目的はおそらく新しい変数を作成することではないため、代わりに要素自体に参照を格納できます。

_element.addEventListener('click',element.fn=function fn() {
    //  Event Code
}, false);
_

後で削除する場合は、次の操作を実行できます。

_element.removeEventListener('click',element.fn, false);
_

イベントリスナーを追加するには、3番目のパラメーター(false)にsameの値が必要です。

しかし、質問自体は別の物乞いです:なぜですか?

より単純な.addEventListener()メソッドではなく.onsomething()を使用する理由は2つあります。

まず、multipleイベントリスナーを追加できます。それらを選択的に削除することになると、これが問題になります。おそらくそれらに名前を付けることになります。それらをすべて削除したい場合は、@ tidy-giantのouterHTMLソリューションが最適です。

次に、イベントをバブリングするのではなく、キャプチャすることを選択するオプションがあります。

どちらの理由も重要でない場合は、より単純なonsomethingメソッドを使用することもできます。

2
Manngo

JQueryを使用している場合は、offメソッドを試してください

$("element").off("event");
0
uingtea

ECMAScript2015(ES2015、ES6)言語仕様を使用すると、このnameAndSelfBind関数を使用して匿名のコールバックを名前付きのコールバックに魔法のように変換し、その本体をバインドして、イベントリスナーが自身を削除できるようにすることもできます。内部および外部スコープから削除される( JSFiddle ):

(function()
{
  // an optional constant to store references to all named and bound functions:
  const arrayOfFormerlyAnonymousFunctions = [],
        removeEventListenerAfterDelay = 3000; // an auxiliary variable for setTimeout

  // this function both names argument function and makes it self-aware,
  // binding it to itself; useful e.g. for event listeners which then will be able
  // self-remove from within an anonymous functions they use as callbacks:
  function nameAndSelfBind(functionToNameAndSelfBind,
                           name = 'namedAndBoundFunction', // optional
                           outerScopeReference)            // optional
  {
    const functionAsObject = {
                                [name]()
                                {
                                  return binder(...arguments);
                                }
                             },
          namedAndBoundFunction = functionAsObject[name];

    // if no arbitrary-naming functionality is required, then the constants above are
    // not needed, and the following function should be just "var namedAndBoundFunction = ":
    var binder = function() 
    { 
      return functionToNameAndSelfBind.bind(namedAndBoundFunction, ...arguments)();
    }

    // this optional functionality allows to assign the function to a outer scope variable
    // if can not be done otherwise; useful for example for the ability to remove event
    // listeners from the outer scope:
    if (typeof outerScopeReference !== 'undefined')
    {
      if (outerScopeReference instanceof Array)
      {
        outerScopeReference.Push(namedAndBoundFunction);
      }
      else
      {
        outerScopeReference = namedAndBoundFunction;
      }
    }
    return namedAndBoundFunction;
  }

  // removeEventListener callback can not remove the listener if the callback is an anonymous
  // function, but thanks to the nameAndSelfBind function it is now possible; this listener
  // removes itself right after the first time being triggered:
  document.addEventListener("visibilitychange", nameAndSelfBind(function(e)
  {
    e.target.removeEventListener('visibilitychange', this, false);
    console.log('\nEvent listener 1 triggered:', e, '\nthis: ', this,
                '\n\nremoveEventListener 1 was called; if "this" value was correct, "'
                + e.type + '"" event will not listened to any more');
  }, undefined, arrayOfFormerlyAnonymousFunctions), false);

  // to prove that deanonymized functions -- even when they have the same 'namedAndBoundFunction'
  // name -- belong to different scopes and hence removing one does not mean removing another,
  // a different event listener is added:
  document.addEventListener("visibilitychange", nameAndSelfBind(function(e)
  {
    console.log('\nEvent listener 2 triggered:', e, '\nthis: ', this);
  }, undefined, arrayOfFormerlyAnonymousFunctions), false);

  // to check that arrayOfFormerlyAnonymousFunctions constant does keep a valid reference to
  // formerly anonymous callback function of one of the event listeners, an attempt to remove
  // it is made:
  setTimeout(function(delay)
  {
    document.removeEventListener('visibilitychange',
             arrayOfFormerlyAnonymousFunctions[arrayOfFormerlyAnonymousFunctions.length - 1],
             false);
    console.log('\nAfter ' + delay + 'ms, an event listener 2 was removed;  if reference in '
                + 'arrayOfFormerlyAnonymousFunctions value was correct, the event will not '
                + 'be listened to any more', arrayOfFormerlyAnonymousFunctions);
  }, removeEventListenerAfterDelay, removeEventListenerAfterDelay);
})();
0
DDRRSS

以下は私にとって十分にうまくいきました。このコードは、別のイベントがリスナーの要素からの削除をトリガーする場合を処理します。事前に関数を宣言する必要はありません。

myElem.addEventListener("click", myFunc = function() { /*do stuff*/ });

/*things happen*/

myElem.removeEventListener("click", myFunc);
0
Ice101781

Jquery .off()メソッドは、.on()で添付されたイベントハンドラーを削除します

0
Compunction