jQuery v1.11
Given an HTML table with 6 columns, I want the cells in the table in columns two, three, five and six to respond to click
events. So if a user clicks on a cell in column one or four, the click
event handler should not be called.
This prevents the event handler from being called when the user clicks in the first column:
$('#my-table').on('click', 'tbody td:not(:first-child)', function (e) {
alert("I've been clicked on!");
});
And his prevents the event handler from being called when the user clicks in column 4:
$('#my-table').on('click', 'tbody td:not(:nth-child(4))', function (e) {
alert("I've been clicked on!");
});
My question is, how do I modify the above so that the event handler is not called when a click occurs in either column one or four.
JSFiddle
Edit: @micnil answered my specific question and I will find knowing the pattern he suggested useful. However, @Oleg took the time to point out a better approach. Rather than binding the event handler to each cell, he suggested that I should bind an event handler to the table. In my case this proves to be better.
Using performance.now()
, discussed here, I get the following results setting up the binding for a jQuery DataTable containing 1,000 rows in Chrome:
Binding the click event to cells took 0.14627581768183972 milliseconds.
Binding the click event to the table took 0.04619236347855349 milliseconds.
You can just put a coma inside the selector:
$('#my-table').on('click', 'tbody td:not(:nth-child(4), :first-child)', function (e) {
alert("I've been clicked on!");
});
I think the best choice in your case is to use the JQuery function index() that will give you the index of clicked td
and you can do the condition you want based to the returned index, take a look at Your updated fiddle.
JS :
$('#my-table').on('click', 'tbody td', function () {
if($(this).index() < 4){ //click in td between 1 and 4
alert('td between 1 and 4 clicked');
}else{ //click in another td
alert('td between 5 and 6 clicked');
}
});
Hope that help.
It's important to understand, that the code like $('#my-table').on('click', 'tbody td:not(:first-child)', function (e) {...});
creates first jQuery wrapper with all <td>
element which corresponds 'tbody td:not(:first-child)'
selector and then bind the event handler separately to every from DOM elements in jQuery object.
I would recommend you to choose another way. You can make one binding of click
on the whole <table>
. The event bubbling will forward the click on the cell to the parent <tr>
and later to the <table>
. It's important that e.target
get your the clicked <td>
.
So the code could be the following:
var columnIndexesIgnore = [0, 3];
$('#my-table').on('click', function (e) {
var $td = $(e.target).closest("td"); // e.target can be <span> instead of <td>
if ($td.length > 0 && $.inArray($td[0].cellIndex, columnIndexesIgnore) < 0) {
// cellIndex is 0-based index. We display in alert 1-based column index
alert("I've been clicked on column " + ($td[0].cellIndex + 1) + "!");
}
});
I used cellIndex property of DOM of <td>
. It's 0-based index of column of the <td>
element. So you need ignore clicks if $td[0].cellIndex
is 0 or 3.
See your demo after the modification: http://jsfiddle.net/OlegKi/spckrjvf/5/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With