禁用匿名事件监听器或将参数和事件传递给非匿名监听器

Disable anonymous event listener or pass params & events to non-anonymous listener

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

$.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. 我不知道如何创建一个命名函数,同时能够以相同的方式传递它,这样 addEventListner 将传递 event 和方向处理程序(如 handlers.left()) 我的 handleSwipe 活动。

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

由于您已经在使用 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 来简化事件的添加和删除,而无需保存对它们的引用,也无需删除 all 个事件那种类型的,谢谢@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');
};