繁体   English   中英

删除匿名事件侦听器

[英]Removing an anonymous event listener

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

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

不更换元素?

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

我通常会将这些添加到该页面上的主对象中,然后您可以在使用该对象时迭代并干净地处理它们。

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

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

匿名绑定事件监听器

删除元素的所有事件侦听器的最简单方法是将其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>

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

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

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

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

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

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

然而,问题本身又引出了另一个问题:为什么?

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

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

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

如果这两个原因都不重要,您可能会决定使用更简单的onsomething方法。

您可以尝试覆盖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.:不推荐,但它会做的伎俩(还没有测试过)

使用文字函数分配事件处理程序很棘手——不仅没有办法删除它们,如果不克隆节点并用克隆替换它——您还可以无意中多次分配相同的处理程序,如果您使用对处理程序的引用。 两个函数总是被视为两个不同的对象,即使它们的字符相同。

编辑:正如Manngo每条评论所建议的那样,您应该使用 .off( )而不是.unbind()因为.unbind()从 jQuery 3.0 开始被弃用,并从 jQuery 1.7 开始被取代。

尽管这是一个老问题并且它没有提到 jQuery,但我会在这里发布我的答案,因为它是搜索词 '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

在这里找到这个。

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

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

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

使用 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);

结束 :) 我在 chrome 92 中测试,工作

我如何为我的 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.

对于我创建的自定义函数,它运行得非常好。

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

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

检查了我的控制台,似乎它有效(任何反馈表示赞赏!)

是的,您可以删除匿名事件侦听器:

const controller = new AbortController();

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

然后像这样删除事件侦听器:

controller.abort();

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

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