Удаление анонимного слушателя события - PullRequest
43 голосов
/ 24 июня 2010

Есть ли способ удалить прослушиватель событий, добавленный так:

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

Без замены элемента?

Ответы [ 11 ]

18 голосов
/ 25 июня 2010

Невозможно чисто удалить обработчик событий, если вы не сохранили ссылку на обработчик событий при создании.

Обычно я добавляю их к основному объекту на этой странице, после чего вы можете выполнять итерацию и аккуратно избавляться от них, когда закончите с этим объектом.

15 голосов
/ 24 июня 2010

Вы можете удалить прослушиватель событий следующим образом:

element.addEventListener("click", function clicked() {
    element.removeEventListener("click", clicked, false);
}, false);
10 голосов
/ 27 сентября 2015

Аноним связанный прослушиватели событий

Самый простой способ удалить все прослушиватели событий для элемента - присвоить его 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>

Анонимный делегированный прослушиватель событий

Единственное предупреждение - делегированные прослушиватели событий или прослушиватели событий в родительском элементе, которые отслеживают каждое событие, соответствующее набору критериев его дочерних элементов. Единственный способ обойти это - изменить элемент так, чтобы он не соответствовал критериям делегированного прослушивателя событий.

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>
4 голосов
/ 26 апреля 2012

Вы можете попробовать перезаписать 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 .: не рекомендуется, но сработает (не проверял)

2 голосов
/ 12 марта 2018

Редактировать: Поскольку Manngo предлагается для комментария, вы должны использовать .off () вместо .unbind () как .unbind () устарело с jQuery 3.0 и заменено с jQuery 1.7.

Несмотря на то, что это старый вопрос и в нем не упоминается jQuery, я опубликую свой ответ здесь, поскольку это первый результат для searchterm 'jquery remove anonymous обработчик событий' .

Вы можете попробовать удалить его, используя функцию .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

Нашел здесь .

1 голос
/ 08 июля 2018

Старый вопрос, но здесь есть решение.

Строго говоря, вы не можете удалить анонимный прослушиватель событий, если не сохраните ссылку на функцию.Поскольку целью использования анонимной функции является, по-видимому, не создание новой переменной, вместо этого вы можете сохранить ссылку в самом элементе:

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

Позже, когда вы захотите удалить ее, вы можете выполнитьследующее:

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

Помните, что третий параметр (false) должен иметь такое же значение , что и для добавления прослушивателя событий.

Однако сам вопроснапрашивается другое: почему?

Есть две причины использовать .addEventListener() вместо более простого .onsomething() метода:

Во-первых, он позволяет множественным прослушивателям событий бытьдобавлено.Это становится проблемой, когда дело доходит до их выборочного удаления: вы, вероятно, в конечном итоге назовете их.Если вы хотите удалить их все, то решение @ 10id * @ tidy-гиганта отлично.

Во-вторых, у вас есть возможность выбрать захват, а не всплывающее событие.

Еслини одна из причин не важна, вы можете решить использовать более простой метод onsomething.

1 голос
/ 24 июня 2010

Назначить обработчики событий с помощью литеральных функций довольно сложно - не только невозможно удалить их, не клонируя узел и не заменив его на клон, но вы также можете случайно назначить один и тот же обработчик несколько раз, что невозможноВы используете ссылку на обработчик.Две функции всегда обрабатываются как два разных объекта, даже если они идентичны символам.

0 голосов
/ 02 марта 2019

С помощью спецификации языка 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 голосов
/ 03 декабря 2017

Метод Jquery .off () удаляет обработчики событий, которые были присоединены с помощью .on ()

0 голосов
/ 03 октября 2016

Если вы используете jQuery, попробуйте off метод

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