Reputation: 273
Using the following source:
<div id="addons">
<div class="addon">
<span class="title"><input type="checkbox" value="addon_1" name="Item 1 title"></span>
<span class="cost">$<em>20</em></span>
</div>
<div class="addon">
<span class="title"><input type="checkbox" value="addon_2" name="Item 2 title"></span>
<span class="cost">$<em>45</em></span>
</div>
<div class="hidden" id="summaries">
<input name="addons_titles" id="addons_titles" type="text" value=""><!-- on checkbox click, add item titles -->
<input name="addons_cost" id="addons_cost" type="text" value=""><!-- on checkbox click, total item cost -->
</div>
</div><!-- end addons -->
I'm trying to
Any thoughts much appreciated - thanks!
Upvotes: 1
Views: 1921
Reputation: 630379
Obalix has it correct, on the tiles though, you can greatly improve performance doing this:
var result = new Array();
$(".addon .title input").each(function() {
result.push($(this).attr("name"));
});
$('#addon_titles').val(result.join('|'));
Because benchmarking is always interesting, here's another test of performance Array vs string concatenation, when you take the jQuery selector performance out of the equation so you're actually comparing the part that's different:
$(function(){
var startTime, endTime, i, result;
startTime = new Date().getTime();
result = '';
for (i = 1; i < 5000000; ++i) {
result += (result.length > 0 ? "|" : "") + "attribute";
}
endTime = new Date().getTime();
$("#method1").html('Method 1: ' + ((endTime - startTime)) + ' ms.');
startTime = new Date().getTime();
result = new Array();
for (i = 1; i < 5000000; ++i) {
result.push("attribute");
}
result.join('|');
endTime = new Date().getTime();
$("#method2").html('Method 2: ' + ((endTime - startTime)) + ' ms.');
});
On this machine, Method 1: 3715 ms, Method 2: 927 ms. It really depends on selectors in this case...it is a micro optimization I agree in most cases, but if you're dealing with a list of items, better to do it in a way that scales from the start. (Assuming it has potential to grow, of course)
Upvotes: 1
Reputation: 16926
Tiles:
var result = '';
$(".addon .title input").each(function(i, n) {
result += (result.length > 0 ? "|" : "") + $(n).attr("name");
});
Sum:
var sum = 0;
$(".addon .cost em").each(function(i, n) {
sum += parseInt($(n).text());
});
Set the values:
$('#addon_titles').val(result);
$('#addon_cost').val(sum);
Nick Craver suggested that using an array and push the items into the array provides better performance. As usually creating an array, pushing items into it and then joining the items together incurrs a small overhead I was interesting what the concrete figures where, so I ran the following test:
var startTime, endTime, i, result;
startTime = new Date().getTime();
for (i = 1; i < 50000; ++i) {
result = '';
$(".addon .title input").each(function(i, n) {
result += (result.length > 0 ? "|" : "") + $(n).attr("name");
});
}
endTime = new Date().getTime();
$("#method1").html('Method 1: ' + ((endTime - startTime)) + ' ms.');
startTime = new Date().getTime();
for (i = 1; i < 50000; ++i) {
result = new Array();
$(".addon .title input").each(function() {
result.push($(this).attr("name"));
});
$('#addon_titles').val(result.join('|'));
}
endTime = new Date().getTime();
$("#method2").html('Method 1: ' + ((endTime - startTime)) + ' ms.');
The test turned out that the first method (string concatenation) took 4926 ms, while the second method took 10359 ms. All tests where based upon the sample data provided in the OP.
Then I wondered what the break even point for the second method was, so I increased the number of input fields. The break even lies about 24 items.
So as a conclusion, if you have a small number of items concatenation provides better performance, while beyond 24 the method using the array is better.
Upvotes: 2