简体   繁体   中英

jQuery click event triggered twice when clicking on Checkbox

I'm playing around with DataTables and I have a table like this :

<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>

What I am trying to do is to be able to click everywhere in the row, and it will select the checkbox of this row :

$('#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);
    }
});

This is working fine, except that now, when I'm clicking on the checkbox itself, it seems it triggers the checkbox click event plus the event bound on the tr .

I've tried something like :

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

But this seems not to work.

Could anyone give me a tip on this please ?

Thanks !

Try to exit the tr click event whenever the user is making a click on checkbox,

$('#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
    }
});

It is because the click event on the checkbox itself is propagated. As a solution you can check whether the actual click target was the checkbox in that case don't do anything in the click handler.

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

Demo: Fiddle

Firstly, remove the iterative identifier you don't need it; at least not solely for identifying the row containing a checkbox.

<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>

Then in jQuery you can attach your event to the tr using traversal to find the related checkbox, and also use stopPropagation() on the click of the checkbox to stop the event being caught twice.

$('#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();
});

Example fiddle

单击如下所示的复选框时,可以确保click事件不会传播到row元素:

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

You can try this.

$('#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);
    }
});

As you already have table row click event.It will also be fired when checkbox click and here you are changing the state of checkbox in your click event.So it is better to preventDefault() event of checkbox.A better solution would be:

$('#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
}
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM