【问题标题】:Disable anonymous event listener or pass params & events to non-anonymous listener禁用匿名事件侦听器或将参数和事件传递给非匿名侦听器
【发布时间】:2020-01-05 21:54:04
【问题描述】:

我正在使用以下侦听器来侦听移动设备上的滑动和触摸事件。它具有以下签名:

$.fn.onSwipe = function(handlers) { // adding a jQuery prototype.
    my_element.addEventListener('touchmove', function(event) {
        handleSwipe(event, handlers.left, handlers.right, handlers.up, handlers.down);
    });
}

我喜欢这个,因为它允许我:

$("foo").onSwipe({
    left: (event) => { ... }, // I can define this right here.
    right: (event) => { ... },
    up: (event) => { ... },
    down: (event) => { ... },
})

对于leftright等,我可以在分配监听器的范围内定义函数,同时还能在监听器中看到事件。

我尝试在我的方向处理程序中执行event.preventDefault,但这仍然会阻止滚动(我想通过删除事件侦听器来启用)。

问题:

  1. 我无法删除该事件,因为它是匿名的。
  2. 我不知道如何创建一个命名函数,同时能够以相同的方式传递它,以便addEventListnerevent 和方向处理程序(如handlers.left())传递给我的@987654329 @事件。

注意:我对使用其他第三方库不感兴趣。

【问题讨论】:

  • 我无法删除该事件,因为它是匿名的。”您只需要对该函数的引用 - 它是否有名称无关紧要。

标签: javascript anonymous-function


【解决方案1】:

由于您已经在使用 jQuery,因此一种选择是使用 .on 附加侦听器,从而允许您使用 .off 将它们全部删除,而无需保存对它们的引用:

$.fn.onSwipe = function(handlers) { // adding a jQuery prototype.
    $(this).on('touchmove', function(event) {
        handleSwipe(event, handlers.left, handlers.right, handlers.up, handlers.down);
    });
};
$.fn.offSwipe = function() {
    $(this).off('touchmove');
};

如果您可能将其他touchmove 侦听器附加到同一元素,那么您需要在调用时保存对已创建函数的引用。不使用 jQuery($.fn 部分除外):

const handlersByElement = new Map();
$.fn.onSwipe = function(handlers) { // adding a jQuery prototype.
  const handler = function(event) {
    handleSwipe(event, handlers.left, handlers.right, handlers.up, handlers.down);
  };
  for (const elm of this) {
    handlersByElement.set(elm, handler);
    elm.addEventListener('touchmove', handler);
  }
};
$.fn.offSwipe = function() {
  for (const elm of this) {
    handlersByElement.set(elm, handler);
    elm.removeEventListener('touchmove', handlersByElement.get(elm));
  }
};

您还可以将 event namespaces 与 jQuery 一起使用来简化事件的添加和删除,而无需保存对它们的引用,也无需删除该类型的 所有 事件,感谢@VLAZ:

$.fn.onSwipe = function(handlers) { // adding a jQuery prototype.
    $(this).on('touchmove.myswiper', function(event) {
        handleSwipe(event, handlers.left, handlers.right, handlers.up, handlers.down);
    });
};
$.fn.offSwipe = function() {
    $(this).off('touchmove.myswiper');
};

【讨论】:

  • $(this).off('touchmove'); 将删除 所有 事件处理程序。对于这个事件,这可能很好,但如果其他代码(特别是第三方代码)为同一事件附加其他处理程序并且您删除它们,通常会导致问题。 is jQuery 中的一个特性隐藏在某个文档的某个地方,它基本上是“命名空间事件”。不确定正式名称是什么,但您可以使用现有事件,然后使用点,后跟您想要的任何字符串。例如$(this).on('touchmove.mySpecialHandler' 这就像$(this).on('touchmove' - 它附加一个处理程序
  • 将在发生touchmove 事件时执行然而,然后您可以使用$(this).off('touchmove.mySpecialHandler'); 仅删除该处理程序 - 任何其他不共享命名空间的处理程序将完好无损。包括为通用非命名空间touchmove 附加的任何处理程序。命名空间可以是您真正想要的任何东西,您可以根据需要为该命名空间附加任意数量的事件。命名空间确实有助于处理更常见的事件,例如 clickinput
猜你喜欢
  • 2011-03-07
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多