Jquery and dynamic table row updates, painful performance
Hello Some is bugging my mind lately, a website I develop has an ability to add new rows to the table via javascript and each time I add a row I have to apply plugins to each row as such:
Assuming .data is my table id:
$('.data tbody tr').each(function(idx) {
$("input:text", this).setMask();
$(this).bindTooltip();
syncRowStatus();
syncRow(this, idx);
});
function countRows(){
return $('.data tbody tr').size();
};
function syncRowStatus(){
var totalRowSize = countRows();
var newHtml = "Total rows: "+ (totalRowSize); //as it is 0-indexed
$(".rowamount").html(newHtml);
};
function syncRow(row, idx){
//fix row id.
$(row).attr("id","row-"+idx );
//fix pk field.
var pk = $("td input:eq(0)" ,row);
pk.attr('name', 'form-'+ idx +'-pk').attr('id', 'id_form-'+ idx +'-pk');
//fix checked field.
var selected = $("td input:eq(1)" ,row);
selected.attr('name', 'form-'+ idx +'-selected').attr('id', 'id_form-'+ idx +'-selected');
//开发者_如何学Cfix start_time field.
var start_time = $("td input:eq(2)" ,row);
start_time.attr('name', 'form-'+ idx +'-start_time').attr('id', 'id_form-'+ idx +'-start_time');
//fix end_time field.
var end_time = $("td input:eq(3)" ,row);
end_time.attr('name', 'form-'+ idx +'-end_time').attr('id', 'id_form-'+ idx +'-end_time');
//fix program name.
var program_name = $("td input:eq(4)" ,row);
program_name.attr('name', 'form-'+ idx +'-program_name').attr('id', 'id_form-'+ idx +'-program_name');
//fix year
var year = $("td input:eq(5)" ,row);
year.attr('name', 'form-'+ idx +'-year').attr('id', 'id_form-'+ idx +'-year');
//And it goes like this...
}
And it applies tooltips, input mask and id / name setting for each row. It works as intended however it is painfully slow to use this method.
Is there any other recommended way of achieving this ?
Regards
My first comment would be that you could just convert the element to a jQuery object once...
$('.data tbody tr').each(function(idx) {
$This = $(this);
$This.find("input:text").setMask();
$This.bindTooltip();
syncRowStatus();
syncRow(this, idx);
});
The performance will improve a little bit just for that change.
After that, it depends on what setMask, bindTooltip, syncRowStatus and syncRow perform and how many rows you have.
If you have to capture events on each row or td then you can capture that event on the parent and delegate it to the children, this way javascript will have to listen to only one event instead of each event attached to each row or cell. heres an example:
$('.data').bind('click', function(e) {
if ($(e.target).hasClass('myselectorclass')) {
// do what you would have done with $('.data .myselectorclass').click(....);
}
}
This event will also capture any new row that you add to the table. Now if only plugins or jquery had a way to do this easily.
it looks like you're mainly just changing the index number every time you add a row, and are doing a lot of work renumbering the rows every time something changes. if that's the case, then you could save a ton of work by changing your structure to:
<table>
<tr data="1"><td></td><td>......</td></tr>
<tr data="2"><td></td><td>......</td></tr>
<tr data="3"><td></td><td>......</td></tr>
</table>
so basically what's going on is that you don't imbed the index number in the input id's, and just stick it in the TR tag, using the data attribute.
this simplifies your code down to:
$('.data tbody tr').each(function(idx) {
$("input:text", this).setMask();
$(this).bindTooltip();
syncRowStatus();
syncRow(this, idx);
});
function syncRowStatus(){
var newHtml = "Total rows: "+$('.data tbody tr').length; //as it is 0-indexed
$(".rowamount").html(newHtml);
};
function syncRow(row, idx){
//fix row id.
$(row).attr("data",idx);
}
now if you want to know which row you're on, the selector would be $('input.ofInterest').parent('td').parent('tr').attr('data');
精彩评论