Reputation: 468
I have the following table.
<table>
<tr>
<td>Name</td>
<td>01</td>
<td>02</td>
<td>03</td>
<td>04</td>
<td>05</td>
</tr>
<tr>
<td class="tdName">Smith</td>
<td class="tdTime" id="td_smith_01">1</td>
<td class="tdTime" id="td_smith_02">%nbsp;</td>
<td class="tdTime" id="td_smith_03">1</td>
<td class="tdTime" id="td_smith_04">%nbsp;</td>
<td class="tdTime" id="td_smith_05">2</td>
</tr>
<tr>
<td class="tdName">Miller</td>
<td class="tdTime" id="td_miller_01">%nbsp;</td>
<td class="tdTime" id="td_miller_02">2</td>
<td class="tdTime" id="td_miller_03">%nbsp;</td>
<td class="tdTime" id="td_miller_04">2</td>
<td class="tdTime" id="td_miller_05">1</td>
</tr>
<tr>
<td class="tdName">Underwood</td>
<td class="tdTime" id="td_underwood_01">%nbsp;</td>
<td class="tdTime" id="td_underwood_02">%nbsp;</td>
<td class="tdTime" id="td_underwood_03">1</td>
<td class="tdTime" id="td_underwood_04">1</td>
<td class="tdTime" id="td_underwood_05">%nbsp;</td>
</tr>
<tr>
<td class="tdName">Stinson</td>
<td class="tdTime" id="td_stinson_01">2</td>
<td class="tdTime" id="td_stinson_02">2</td>
<td class="tdTime" id="td_stinson_03">%nbsp;</td>
<td class="tdTime" id="td_stinson_04">%nbsp;</td>
<td class="tdTime" id="td_stinson_05">1</td>
</tr>
</table>
In reality it's way larger and more complex. Now I want to add a click listener do each and every time cell of the table, so every cell of the class "tdTime", so I added:
var tdTimes = $(".tdTime");
tdTimes.onclick(
function() {
switch($(this).html()) {
...a switch to change the time in the td.
}
}
);
As I mentioned the real table is much bigger (length of tdTimes > 15,000) and so the IE needs about ~8,000ms to add the listener to every cell, Chrome still needs about 3,000ms. On many sites it's suggested to use ids as a selector to make this faster but as you can see I already have ids in use and it is nearly impossible for me to use those ids in that case because the table is - again - a lot more complex than the simple example.
What would you suggest to speed up the process? In another post I read about a tip to give the selectors a context, should I maybe give the table rows an consecutive id ("trTime1", "trTime2", ...), then remember the amount of those rows and later do a for loop to add the listener? Something like:
for(var i = 1; i <= trTimelength; i++) {
var tdTimes = $('.tdTime', '#trTime' + i)
tdTimes.click(
...
)
};
Thanks for your help, guys!
EDIT: As A. Wolff correctly mentioned 15,000 cells are way too many to display - I would therefor like to add, that most of those cells are hidden at the start. So after the page is loaded I have no problem with performance. (But unfortunately the cells need the listener anyway)
Upvotes: 0
Views: 90
Reputation: 6451
Do not attach event handler to each cell. It's very inefficient, and consumes a lot of memory.
Use event bubbling feature and attach a handler to higher level element, to the table in this case.
try something like
$("table#tblid").on("click", "td.tdTime", function(e) {
console.log("Td clicked", e);
console.log(e.target);
});
NOTE: As correctly mentioned in the comment (by @A.Wolf) below this is not a shortcut for adding all the handlers at once. This ads only a single handler to the table element which contains all the td elements. Table can see the click event on child td, because of the mechanism known as 'event propagation' or 'event bubbling'. It uses much less resources than and less error prone than adding handlers to individual elements. It works even if you dynamically add td elements later on to the table.
Check this jsFiddle: http://jsfiddle.net/BuddhiP/prv6y/
Upvotes: 3