Отключить прослушиватель анонимных событий или передать параметры и события неанонимным прослушивателям - PullRequest
1 голос
/ 06 января 2020

Я использую следующий слушатель для прослушивания событий смахивания и касания на мобильном телефоне. Он имеет следующую подпись:

$.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) => { ... },
})

Для left, right и т. Д., Я могу определять функции в области назначения слушателя, в то же время имея возможность видеть событие в слушателе.

Я пытался сделать event.preventDefault в моих обработчиках направления, но это все еще не позволяет прокручивать (что я хотел бы включить удалив прослушиватель событий).

Проблема:

  1. Я не могу удалить событие, так как оно анонимное.
  2. Не знаю не знаю, как я мог бы создать именованную функцию, при этом передав ее таким же образом, чтобы addEventListner передавал обработчики event и направления (например, handlers.left()) в мое handleSwipe событие.

Примечание. Меня не интересуют другие сторонние библиотеки.

1 Ответ

3 голосов
/ 06 января 2020

Поскольку вы уже используете 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));
  }
};

Вы также можете использовать пространства имен событий с 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');
};
...