删除匿名事件监听器

72

有没有办法删除像这样添加的事件监听器:

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

不替换元素?


6
如果有多个匿名监听者,你该如何选择正确的一个进行移除? - Sean Hogan
1
@Sean Hogan:什么?我不明白你问的与我的问题有什么关系。 - erikvold
1
@Sean:我认为意图是从事件处理程序中删除事件监听器。 - icktoofay
14个回答

1
Jquery的.off()方法会移除使用.on()绑定的事件处理程序。

1

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

我如何为我的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)()));

检查了我的控制台,似乎它起作用了(欢迎任何反馈!)


-2

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

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

/*things happen*/

myElem.removeEventListener("click", myFunc);

4
你违反了问题的限制。 - Matthew Read

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接