删除匿名事件监听

无论如何,要删除这样添加的事件侦听器:

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

不更换元素?

11个解决方案
19 votes

除非您在创建时存储了对事件处理程序的引用,否则无法彻底删除事件处理程序。

通常,我会将它们添加到该页面上的主要对象中,然后在处理完该对象后可以对其进行迭代和清理。

Joe answered 2020-08-01T14:38:32Z
16 votes

您可以这样删除事件监听器:

element.addEventListener("click", function clicked() {
    element.removeEventListener("click", clicked, false);
}, false);
icktoofay answered 2020-08-01T14:38:54Z
10 votes

匿名绑定事件监听器

删除元素的所有事件侦听器的最简单方法是为其分配<a id="demo" href="javascript:void(0)">Click Me</a>。 这是通过HTML解析器发送HTML的字符串表示形式,并将解析的HTML分配给元素。 因为没有传递JavaScript,所以将没有绑定的事件侦听器。

<a id="demo" href="javascript:void(0)">Click Me</a>
<a id="demo" href="javascript:void(0)">Click Me</a>


匿名委托事件监听器

一个警告是委派的事件侦听器,或父元素上的事件侦听器,它们监视与子元素上的一组条件匹配的每个事件。 克服问题的唯一方法是更改元素,使其不符合委托事件侦听器的条件。

<a id="demo" href="javascript:void(0)">Click Me</a>
<a id="demo" href="javascript:void(0)">Click Me</a>

Jason Gross answered 2020-08-01T14:39:28Z
4 votes

您可以尝试覆盖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 .:不建议这样做,但是可以解决问题(尚未测试)

w35l3y answered 2020-08-01T14:39:56Z
3 votes

编辑:正如Manngo在每个注释中建议的那样,您应该使用.off()而不是.unbind(),因为.unbind()从jQuery 3.0开始就已弃用,并自jQuery 1.7起被取代。

即使这是一个古老的问题,它也没有提到jQuery,但我将在这里发布我的答案,因为这是搜索字词“ jquery removeonymous event handler”的第一个结果。

您可以尝试使用.off()函数将其删除。

<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>
<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

在这里找到这个。

general64 answered 2020-08-01T14:40:35Z
2 votes

使用文字函数分配事件处理程序很棘手-不仅没有办法删除它们,而且不克隆节点并用克隆替换它-您还可能无意中多次分配了相同的处理程序,如果使用 引用处理程序。 即使两个函数的字符相同,也始终将其视为两个不同的对象。

kennebec answered 2020-08-01T14:40:55Z
2 votes

旧问题,但这是一个解决方案。

严格来说,除非您存储对该函数的引用,否则您将无法删除匿名事件监听器。 由于使用匿名函数的目标可能不是创建新变量,因此您可以将引用存储在元素本身中:

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

以后,当您要删除它时,可以执行以下操作:

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

请记住,第三个参数(onsomething)必须具有与添加事件侦听器相同的值。

但是,这个问题本身又引出了一个问题:为什么?

使用onsomething而不是使用更简单的.onsomething()方法有两个原因:

首先,它允许添加多个事件侦听器。 在有选择地删除它们时,这成为一个问题:您可能最终会命名它们。 如果您要删除它们,那么@ tidy-giant的onsomething解决方案非常好。

其次,您确实可以选择捕获而不是冒泡事件。

如果两个理由都不重要,则可以决定使用更简单的onsomething方法。

Manngo answered 2020-08-01T14:41:51Z
0 votes

以下内容对我来说足够好。 该代码处理另一个事件触发侦听器从元素中移除的情况。 无需事先进行函数声明。

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

/*things happen*/

myElem.removeEventListener("click", myFunc);
Ice101781 answered 2020-08-01T14:42:12Z
0 votes

如果您使用的是jQuery,请尝试off方法

$("element").off("event");
uingtea answered 2020-08-01T14:42:31Z
0 votes

jQuery .off()方法删除与.on()关联的事件处理程序

Compunction answered 2020-08-01T14:42:51Z
0 votes

使用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);
})();
DDRRSS answered 2020-08-01T14:43:12Z
translate from https://stackoverflow.com:/questions/3106605/removing-an-anonymous-event-listener