【问题标题】:Issues with event delegation on same container同一容器上的事件委托问题
【发布时间】:2018-07-12 19:30:06
【问题描述】:

我有一个函数,简化如下:

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,什么都不会发生。

【问题讨论】:

  • 你应该提到你正在使用 jQuery。
  • 每次调用fooFunction()都会覆盖容器的foobarData数据。
  • 顺便说一句,在您的代码中 $container 将是一个字符串,而不是一个 jQuery 对象。

标签: javascript jquery event-delegation


【解决方案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);
      }
    });
  }
}

【讨论】:

  • 感谢您的帮助!我的.data() 被调用了两次,因此第二次调用会覆盖第一次调用,我没有看到!这将解决它!谢谢!
猜你喜欢
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 2011-03-29
  • 1970-01-01
相关资源
最近更新 更多