0

I have the following Javascript that runs in my popup window and which uses jQuery to select the checked checkboxes from the parent window and then for each checkbox it again uses jQuery to select associated data from hidden fields (also from the parent window).

var chked = $('[name^="mycheckbox_"]:checked', opener.frmMain);
var hdn;
var fieldId;
var data = {};
$.each(chked, function (key, field) {

    hdn = field.id.replace('chk_', 'hdn_');

    data[hdn + 'id'] = $('[name="' + hdn + 'id"]', opener.frmMain).val();
    data[hdn + 'name'] = $('[name="' + hdn + 'name"]', opener.frmMain).val();
});

The issue I'm encountering is that it can take over a minute to execute the $.each loop when there are over a thousand checkboxes. If I comment out the following lines in the $.each loop then the performance improves significantly:

data[hdn + 'id'] = $('[name="' + hdn + 'id"]', opener.frmMain).val();
data[hdn + 'name'] = $('[name="' + hdn + 'name"]', opener.frmMain).val();

I'm trying to figure out how to improve the performance and yet still load the associated hidden fields. One option could be to use jQuery to query the hidden fields up-front before the loop executes and then perform a lookup in the array returned from this query in the loop. However I'm not sure that performing an array lookup within the $.each loop would be any quicker than the existing jQuery calls. Would appreciate any input.

2
  • 1
    try using DOM methods instead, use ID's for your checkboxes Commented Feb 18, 2016 at 20:56
  • 1
    also, storing data in so many hidden fields seems inefficient anyway, but without knowing the specifics of your specific design, that's just my opinion Commented Feb 18, 2016 at 21:04

1 Answer 1

1

I would suggest using the Ends With Selector and caching the elements it returns. This should eliminate the majority of the redundant DOM traversal since you'll be able to filter using a much smaller list:

// Retrieve all possible matches from the DOM at once
var $endsInId = $("[name$='id']", opener.frmMain);
var $endsInName = $("[name$='name']", opener.frmMain);

$.each(chked, function (key, field) {

    hdn = field.id.replace('chk_', 'hdn_');

    data[hdn + 'id'] = $endsInId.filter('[name="' + hdn + 'id"]').val();
    data[hdn + 'name'] = $endsInName.filter('[name="' + hdn + 'name"]').val();
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. This resulted in a massive performance improvement. Marking as the correct answer.
@aw1975 It might also be possible to make it slightly faster to simply assume $endsInId and $endsInName only contain the data values you're looking for and map them to the data object directly. But I don't know if that's the case here or if a further performance gain is necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.