I have a table of 50 odd rows with 11 columns. Each row has a unique id
made up of id="row_<clientid>_rownumber"
. There is a checkbox in the second column with id="group_<clientid>_<petid>_rownumber"
Redacted Screenshot http://www.forsythesit.com.au/res/img/slowrowremoval.jpg
When the user clicks a checkbox I want to remove all rows except any that belong to the selected client. I have code that works as follows:
var sClient = $(this).attr("id").substring(6); // trim off group_
sClient = sClient.substring(0,sClient.indexOf("_")); // trim off anything after clientid
$("tr[id^=row_]").not("tr[id^=row_" + sClient + "]").remove();
The problem is it takes so long that in IE I get the "script is taking too long" warning.
Is there a faster method to remove many rows?
BTW: It takes 4.4 seconds using jQuery 1.4.3 and 1.3 seconds with jQuery 1.4.2
Problem Solved thanks to all. Final hint provided by @VisusZhao. This is final working snippet:
var KeepRows = $("#bookingstable tbody tr[id^=row_" + sClient + "_]");
$("#bookingstable tbody").empty();
$("#bookingst开发者_Go百科able tbody").append(KeepRows);
Thank you all
you can first store the row for the client,
var clientRow = $('#row_' + sClient);
then empty the table
$('#table_id tbody').empty();
then insert the row back
$('#table_id tbody').append(clientRow);
this will take no loop, so its constant time
First of all, give the table an id.
<table id="departures">
Store all of the required rows in a jQuery object, and only those inside #departures
.
var $departures = $("#departures");
var $rows = $("tr[id^=row_]", $departures); //
This way, jQuery won't have to traverse the DOM each time you perform a function because it'll be stored inside the object.
Then use your code as usual
var sClient = $(this).attr("id").substring(6); // trim off group_
sClient = sClient.substring(0,sClient.indexOf("_")); // trim off _row
While replacing the last line with this
$rows.not("tr[id^=row_" + sClient + "]", $departures).remove();
I think you can try using .filter
instead, like this:
var sClient = this.id.substring(6); // trim off group_
$("#table_id tr").filter(function(){
return (this.id.indexOf('row') === 0 && this.id !== sClient);
}).remove();
Or maybe, give the rows that belongs to each client a class:
var sClient = this.id.substring(6); // trim off group_
$('#table tr.' + sClient).remove();
Neither of these are guaranteed to be faster, unlike Marko's answer above, but they are different ways to making this work, and may be faster for IE.
Definitely id your table and use that as your jQuery context. Also store the table jQuery object as well - though you probably won't see much improvement from that. I might try applying a class to each of your rows. For instance, give each row a class of the client they belong to. Then, this should do the trick:
var tableElement = $("#table_id"); // only do this once on page load
tableElement.find("tr:not(." + sClient + ")").hide();
No guarantee this will be faster, but it might be worth a try.
I would start by adding an ID to the table:
<table id="alldepartures">
Next, for each row keep the id
if you need it, but also add a CSS class in the format "client_{id}":
<tr class="client_123">
This is ok, because you can have several rows with the same class.
Then in your code:
var sClient = $(this).attr("id").split('_')[1];
//remove all rows that don't have this class
$('#alldepartures').find('tr[class!=client_' + sClient + ']').remove();
I think the other code may be suffering especially in IE with trying to do matching based on ID as jQuery has to do extra work in IE to overcome their faulty getElementById(id) implementation.
精彩评论