【问题标题】:Click listener firing twice due to nested element由于嵌套元素,单击侦听器触发两次
【发布时间】:2012-03-21 20:52:44
【问题描述】:

我有以下听众:

$('td').on('click', '.time_note', function (e) { // When the user clicks the note div
    alert('note click');
});

$('table').on('click', 'td', function(e) {
    alert('time click');
});

我需要两种不同的操作,具体取决于是单击了笔记还是单击了整个单元格。但是,如果单击注释,我尝试这样做 - 单元格也是如此。随后,这两个动作都会被触发。很有道理。

但是,我不希望这种情况发生。如果单击注释,则不应触发整个单元格的操作,反之亦然。有什么方法可以做到这一点?我尝试使用.off,但没有成功。

【问题讨论】:

标签: javascript jquery


【解决方案1】:

你不能……

除非两个事件都是委托事件,否则您无法停止传播。

由于 .live() 方法在事件传播到文档顶部后处理事件,因此无法停止实时事件的传播。同样,由 .delegate() 处理的事件将传播到它们被委托的元素;在调用委托的事件处理程序时,绑定在 DOM 树中它下面的任何元素上的事件处理程序将已经执行。因此,这些处理程序可能会阻止委托处理程序通过调用 event.stopPropagation() 或返回 false 来触发。

docs

注意: on 在这种情况下就像 delegate。我猜他们只是没有更新文档...


更新:

  • 如果两个事件都是委托事件,它可以工作:@josef DEMO
  • 如果其他事件不是委托的,它将不起作用:DEMO

委托和直接事件有什么区别:

事件处理程序仅绑定到当前选定的元素;当您的代码调用 .on() 时,它们必须存在于页面上。为确保元素存在并且可以被选择,请在页面 HTML 标记中的元素的文档就绪处理程序内执行事件绑定。如果将新 HTML 注入页面,请在将新 HTML 放入页面后选择元素并附加事件处理程序。或者,使用委托事件来附加事件处理程序,如下所述。

委托事件的优点是它们可以处理来自以后添加到文档的后代元素的事件。通过选择在附加委托事件处理程序时保证存在的元素,您可以使用委托事件来避免频繁附加和删除事件处理程序的需要。例如,此元素可以是模型-视图-控制器设计中视图的容器元素,或者如果事件处理程序想要监视文档中的所有冒泡事件,则可以是文档。在加载任何其他 HTML 之前,文档元素在文档头部是可用的,因此在此处附加事件是安全的,而无需等待文档准备好。

【讨论】:

  • 不知道你为什么说我不能,我刚试过stopPropagation,效果很好..
  • @DoctorOreo。这取决于 DOM 以及您尝试阻止的处理程序。我会做一个小提琴给你看。
  • @DoctorOreo。检查this小提琴。你的作品只是因为它们都是委托事件。
  • 我看到两者之间的唯一区别是选择器的数量——你有table td——是livedelegate事件之间的区别吗?
  • @DoctorOreo。我添加了文档答案并更新了小提琴。你有区别吗?
【解决方案2】:

尝试检查 event.currentTarget:

$('table').on('click', 'td', function(e) {
    if(e.currentTarget.tagName.toLowerCase() == 'td') {
        alert('time click');
    } else {
        alert('note click');
    }
});

您可以找到更多信息here

【讨论】:

    【解决方案3】:

    DEMO

    就是这种情况:.note 的处理程序在td 上。点击.note,事件冒泡到td,在那里它触发处理程序。 但你并没有就此止步。事件冒泡到根,单击子元素等同于单击它的祖先。这就是为什么它就像单击处理程序在table 中的td

    在早期,你应该阻止它。

    $(function() {
    
        $('td').on('click', '.note', function(e) {
            alert('note click');
            return false; //prevent bubbling to the second handler
        });
    
        $('table').on('click', 'td', function(e) {
            alert('td click');
        });
    
    });​
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多