Проблемы с делегированием событий в том же контейнере

У меня есть функция, упрощенная так:

var fooFunction = function($container, data) {
  $container.data('foobarData', data);

  $container.on('click', 'a', function(e) {
    var data = $(e.delegateTarget).data('foobarData');
    var $target = $(e.currentTarget);

    if (typeof data.validateFunction === 'function' && !data.validateFunction(e)) {
      return;
    }

    e.preventDefault();
    e.stopPropagation();

    // Do stuff
    console.log(data.returnText);
  });
};

fooFunction('.same-container', {
  validateFunction: function(event) {
    return $(e.currentTarget).closest('.type-companies').length ? true : false;
  },
  returnText: 'Hello Company!',
});

fooFunction('.same-container', {
  validateFunction: function(event) {
    return $(e.currentTarget).closest('.type-humans').length ? true : false;
  },
  returnText: 'Hello Human!',
})

Я использую делегирование событий в том же контейнере (.same-container) с кастомом validateFunction() проверить, если код в // Do stuff должен бежать.

Для каждого fooFunction() инициация, у меня есть другая логика, которая будет вызвана // Do stuff, Проблема в том, что эти два делегирования событий конфликтуют. Кажется, только один из них вызывается и перезаписывает другой.

Как я могу иметь несколько делегаций событий с возможностью определить через пользовательскую функцию validateFunction, какую из них следует вызывать. я использую preventDefault() + stopPropagation() так что нажмите на <a>ничего не происходит, пока validateFunction() возвращается true,

1 ответ

Решение

Проблема в том, что вы перезаписываете $(e.delegateTarget).data('foobarData') каждый раз.

Вместо этого вы можете добавить параметры в массив, который вы будете циклически повторять, пока не будет найдено совпадение.

var fooFunction = function($container, data) {
  var oldData = $container.data('foobarData', data);
  if (oldData) { // Already delegated, add the new data
    oldData.push(data);
    $container.data('foobarData', oldData);
  } else { // First time, create initial data and delegate handler
    $container.data('foobarData', [data]);
    $container.on('click', 'a', function(e) {
      var data = $(e.delegateTarget).data('foobarData');
      var $target = $(e.currentTarget);
      var index = data.find(data => typeof data.validateFunction === 'function' && !data.validateFunction(e));
      if (index > -1) {
        var foundData = data[index]

        e.preventDefault();
        e.stopPropagation();

        // Do stuff
        console.log(foundData.returnText);
      }
    });
  }
}

Другие вопросы по тегам