点击复选框时触发两次jQuery点击事件

jQuery click event triggered twice when clicking on Checkbox

本文关键字:两次 jQuery 事件 复选框      更新时间:2023-09-26

我正在摆弄DataTables,我有一个这样的表:

<table id='dt'>
    <thead><!-- Some Header --></thead>
    <tbody>
        <tr data-lineid=1>
            <td><input type='checkbox' class='checked_entry' id='checked_1'></td>
            <td>Column 1</td>
            <td>Column 2</td>
        </tr>
        <!-- Rest of the table -->
    </tbody>
</table>

我想做的是能够点击行中的任何地方,它会选择这一行的复选框:

$('#dt tbody').on('click', 'tr', function() {
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
    } else {
        $('#checked_'+id).prop('checked', true);
    }
});

这是正常工作,除了现在,当我点击复选框本身,它似乎触发复选框点击事件加上事件绑定在tr

我试过这样做:

$('#dt tbody').on('click', 'tr :not(input)', function() { ... });

但这似乎不起作用。

有谁能给我点建议吗?

谢谢!

尝试在用户点击复选框时退出tr点击事件,

$('#dt tbody').on('click', 'tr', function(e) {
    if($(e.target).is('input')) { return; }
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
        // ... and some other stuff
    } else {
        $('#checked_'+id).prop('checked', true);
        // ... and some other stuff
    }
});

这是因为复选框本身的click事件被传播了。作为一种解决方案,你可以检查实际的点击目标是否是复选框,在这种情况下,不要在点击处理程序中做任何事情。

$('#dt tbody').on('click', 'tr', function (e) {
    if (!$(e.target).is('input:checkbox')) {
        $(this).find('input:checkbox').prop('checked', function (i, checked) {
            return !checked;
        })
    }
});

演示:小提琴

首先,删除你不需要的迭代标识符;至少不仅仅用于标识包含复选框的行。

<table id='dt'>
    <thead><!-- Some Header --></thead>
    <tbody>
        <tr>
            <td><input type='checkbox' class='checked_entry' /></td>
            <td>Column 1</td>
            <td>Column 2</td>
        </tr>
    </tbody>
</table>

然后在jQuery中,您可以使用遍历将您的事件附加到tr以找到相关的复选框,并在单击复选框时使用stopPropagation()来阻止事件被捕获两次。

$('#dt tbody').on('click', 'tr', function() {
    var $checkbox = $(this).find(':checkbox');
    $checkbox.prop('checked', !$checkbox.prop('checked'));
});
$('#dt input:checkbox').click(function(e) {
    e.stopPropagation();
});

例子小提琴

当你像这样单击复选框时,你可以确保click事件不会传播到row元素:

$('#dt tbody input').on('click', function(e) { e.stopPropagation(); });

你可以试试这个

$('#dt tbody').on('click', 'tr', function(event) {
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
    } else {
        $('#checked_'+id).prop('checked', true);
    }
      event.preventDefault();
});
$('#dt tbody').on('click', 'tr', function(e) {
    e.preventDefault();
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
    } else {
        $('#checked_'+id).prop('checked', true);
    }
});

由于您已经有了表行单击事件。当复选框单击时,它也会被触发,这里您正在更改单击事件中复选框的状态。因此最好使用复选框的preventDefault()事件。一个更好的解决方案是:

$('#dt tbody').on('click', 'tr', function(e) {
e.preventDefault();
var id = $(this).data('lineid');
if ($('#checked_'+id).prop('checked')) {
    $('#checked_'+id).prop('checked', false);
    // ... and some other stuff
} else {
    $('#checked_'+id).prop('checked', true);
    // ... and some other stuff
}
});