简体   繁体   English

删除匿名事件侦听器

[英]Removing an anonymous event listener

Is there anyway to remove an event listener added like this:无论如何要删除这样添加的事件侦听器:

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

Without replacing the element?不更换元素?

There is no way to cleanly remove an event handler unless you stored a reference to the event handler at creation.除非您在创建时存储了对事件处理程序的引用,否则无法彻底删除事件处理程序。

I will generally add these to the main object on that page, then you can iterate and cleanly dispose of them when done with that object.我通常会将这些添加到该页面上的主对象中,然后您可以在使用该对象时迭代并干净地处理它们。

You could remove the event listener like this:您可以像这样删除事件侦听器:

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

Anonymous bound event listeners匿名绑定事件监听器

The easiest way to remove all event listeners for an element is to assign its outerHTML to itself.删除元素的所有事件侦听器的最简单方法是将其outerHTML分配给它自己。 What this does is send a string representation of the HTML through the HTML parser and assign the parsed HTML to the element.它的作用是通过 HTML 解析器发送 HTML 的字符串表示,并将解析的 HTML 分配给元素。 Because no JavaScript is passed, there will be no bound event listeners.因为没有传递 JavaScript,所以不会有绑定的事件侦听器。

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


Anonymous delegated event listeners匿名委托事件监听器

The one caveat is delegated event listeners, or event listeners on a parent element that watch for every event matching a set of criteria on its children.一个警告是委派的事件侦听器,或父元素上的事件侦听器,用于监视与其子元素上的一组条件匹配的每个事件。 The only way to get past that is to alter the element to not meet the criteria of the delegated event listener.解决这个问题的唯一方法是将元素更改为不符合委托事件侦听器的标准。

 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>

Old Question, but here is a solution.老问题,但这是一个解决方案。

Strictly speaking you can't remove an anonymous event listener unless you store a reference to the function.严格来说,除非您存储对该函数的引用,否则您无法删除匿名事件侦听器。 Since the goal of using an anonymous function is presumably not to create a new variable, you could instead store the reference in the element itself:由于使用匿名函数的目的可能不是创建新变量,因此您可以将引用存储在元素本身中:

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

Later, when you want to remove it, you can do the following:稍后,当您要删除它时,可以执行以下操作:

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

Remember, the third parameter ( false ) must have the same value as for adding the Event Listener.请记住,第三个参数 ( false ) 必须具有与添加事件侦听器相同的值。

However, the question itself begs another: why?然而,问题本身又引出了另一个问题:为什么?

There are two reasons to use .addEventListener() rather than the simpler .onsomething() method:使用 .addEventListener( .addEventListener()而不是更简单的.onsomething()方法有两个原因:

First, it allows multiple event listeners to be added.首先,它允许添加多个事件监听器。 This becomes a problem when it comes to removing them selectively: you will probably end up naming them.当有选择地删除它们时,这会成为一个问题:您最终可能会命名它们。 If you want to remove them all, then @tidy-giant's outerHTML solution is excellent.如果您想将它们全部删除,那么@tidy-giant 的outerHTML解决方案非常棒。

Second, you do have the option of choosing to capture rather than bubble the event.其次,您确实可以选择捕获而不是冒泡事件。

If neither reason is important, you may well decide to use the simpler onsomething method.如果这两个原因都不重要,您可能会决定使用更简单的onsomething方法。

You may try to overwrite element.addEventListener and do whatever you want.您可以尝试覆盖element.addEventListener并做任何您想做的事情。
Something like:就像是:

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.: it is not recommended, but it will do the trick (haven't tested it) ps.:不推荐,但它会做的伎俩(还没有测试过)

Assigning event handlers with literal functions is tricky- not only is there no way to remove them, without cloning the node and replacing it with the clone- you also can inadvertantly assign the same handler multiple times, which can't happen if you use a reference to a handler.使用文字函数分配事件处理程序很棘手——不仅没有办法删除它们,如果不克隆节点并用克隆替换它——您还可以无意中多次分配相同的处理程序,如果您使用对处理程序的引用。 Two functions are always treated as two different objects, even if they are character identical.两个函数总是被视为两个不同的对象,即使它们的字符相同。

Edit: As Manngo suggested per comment, you should use .off() instead of .unbind() as .unbind() is deprecated as of jQuery 3.0 and superseded since jQuery 1.7.编辑:正如Manngo每条评论所建议的那样,您应该使用 .off( )而不是.unbind()因为.unbind()从 jQuery 3.0 开始被弃用,并从 jQuery 1.7 开始被取代。

Even though this an old question and it does not mention jQuery I will post my answer here as it is the first result for the searchterm 'jquery remove anonymous event handler' .尽管这是一个老问题并且它没有提到 jQuery,但我会在这里发布我的答案,因为它是搜索词 'jquery remove anonymous event handler'的第一个结果。

You could try removing it using the .off() function.您可以尝试使用.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>

However this only works if you've added the listener using jQuery - not .addEventListener但是,这仅在您使用 jQuery 添加侦听器时才有效 - 而不是.addEventListener

Found this here . 在这里找到这个。

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

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

Jquery .off() 方法删除与 .on() 附加的事件处理程序

With ECMAScript2015 (ES2015, ES6) language specification, it is possible to do with this nameAndSelfBind function that magically turns an anonymous callback into a named one and even binds its body to itself, allowing the event listener to remove itself from within as well as it to be removed from an outer scope ( JSFiddle ):使用 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);
})();
//get Event
let obj = window; //for example
let eventStr= "blur"; //for example
let index= 0; //you can console.log(getEventListeners(obj)[eventStr]) and check index
let e = getEventListeners(obj)[eventStr][index];
//remove this event
obj .removeEventListener(eventStr,e.listener,e.useCapture);

THE END :) i test in chrome 92, worked结束 :) 我在 chrome 92 中测试,工作

How I used options parameter for my customEvent我如何为我的 customEvent 使用 options 参数

options Optional
An object that specifies characteristics about the event listener. The available options are:
...
**once**
A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.

for my custom function that I created, it worked quite nicely.对于我创建的自定义函数,它运行得非常好。

const addItemOpenEventListener = (item, openItem) => {
  document.addEventListener('order:open', ({detail}) => {
    if(detail.id === item.id) {
      openItem();
    }
  }, {once: true})
};

el.addItemOpenEventListener(item, () => dispatch(itemOpen)()));

checked my console, seems like it worked (any feedback appreciated!)检查了我的控制台,似乎它有效(任何反馈表示赞赏!)

Yes you can remove an anonymous event listener:是的,您可以删除匿名事件侦听器:

const controller = new AbortController();

document.addEventListener(
  "click",
  () => {
    // do function stuff
  },
  { signal: controller.signal }
);

You then remove the event listener like this:然后像这样删除事件侦听器:

controller.abort();

The following worked well enough for me.以下对我来说足够好。 The code handles the case where another event triggers the listener's removal from the element.该代码处理另一个事件触发侦听器从元素中删除的情况。 No need for function declarations beforehand.无需事先声明函数。

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

/*things happen*/

myElem.removeEventListener("click", myFunc);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM