直接点击复选框时,它不会改变。

4
我有一张数据表格,每行都有一个复选框供用户选择项目。
我使用以下jQuery代码,允许用户通过单击行中的任何位置来选择项目:
$("tbody tr").click(function() {
    var checkbox = $(this).find(':checkbox');
    checkbox.attr('checked', !checkbox.attr('checked'));
});

问题在于,如果我直接点击复选框,什么也不会发生。即使复选框未被选中,它仍然保持未选中状态。如果我在行的任何其他位置单击,复选框会更改状态。
我认为jQuery代码导致动作执行两次。如果我点击复选框,复选框将更改,但是然后将执行单击行的jQuery代码,并且复选框将被更改回来。不确定是否实际发生了这种情况,但那是我的猜测。
当用户单击行时,如何切换复选框,并在直接单击复选框时执行相同的操作?
4个回答

4

通过检查事件信息来确定单击了哪个项目。 如果是复选框,则不运行代码。 否则,切换已选属性。

$("tbody tr").click(function(e) {
        e = e || event;
        var isCheckbox = $(e.target).is(":checkbox");
        if (!isCheckbox) {
            var checkbox = $(this).find(':checkbox');
            checkbox.attr('checked', !checkbox.attr('checked'));
        }
});

这是一个很好的解决方案,可能比我的更好,但你应该在函数开头添加这一行代码。(e = e || event;) 这将在浏览器中正确处理事件。 - John Hartsock

3
这是因为复选框在tbody tr中。如果你逐步执行代码,你会注意到它被选中,但然后被你的click函数取消选中。将你的click函数改为排除包含复选框的td。
$("tbody tr td").click(function() { 
    if ($("input:checkbox", $(this)).length) {
       //td contains check box  do nothing
    } else {
      var checkbox = $(this).find(':checkbox'); 
      checkbox.attr('checked', !checkbox.attr('checked')); 
    }
}); 

如果td包含除复选框以外的任何内容,例如标签,当您单击标签时,将不会发生任何事情。示例:http://jsfiddle.net/crX7L/。我发布了另一个建议,它查看事件并根据该事件决定要执行什么操作。 - Simen Echholt

0
你正在捕获行上的点击事件。如果复选框在TR内,则会触发该事件,并且您将反转“checked”属性。一种解决方案是在TR中的每个TD上放置事件,除了包含复选框的TD。

0
如果问题是事件实际上被触发了两次(这似乎是一个合理的假设),那么您应该尝试使用 event.preventDefault()event.stopPropagation() 事件方法。它们应该阻止事件到达复选框本身。

好主意,但在我看来,防止浏览器实现其默认行为应该是最后的手段。阻止事件传播可能会在重构代码或未来实现时引起其他问题。 - John Hartsock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接