最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery click event triggered twice when clicking on Checkbox - Stack Overflow

programmeradmin4浏览0评论

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 !

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 !

Share Improve this question asked Jun 19, 2014 at 8:29 BMNBMN 8,50814 gold badges50 silver badges80 bronze badges
Add a ment  | 

7 Answers 7

Reset to default 3

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

You could make sure the click event doesn't propagate to the row element when you click the checkbox like this:

$('#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
}
});
发布评论

评论列表(0)

  1. 暂无评论