开发者

Better performance for selecting options by value with jQuery?

I am trying to work out some performance problems with some JavaScript I've been working on for a few days. One of the pieces of the functions is below:

var removeAddress = function(pk) {
    var startTime = new Date();
    jQuery('.add_driver select.primary_address:has(option[value=' + pk + ']:selected)').each(function(c, o) {
        console.log("Shouldn't get here yet...");
        showInputs(o);
    });
    console.log('removeAddress1:  ', (new Date() - startTime) / 1000);
    jQuery('.add_driver select.primary_address option[value=' + pk + ']').remove();
    console.log('removeAddress2:  ', (new Date() - startTime) / 1000);
};

This code is quite peppy in Firefox:

removeAddress1:  0.004
removeAddres开发者_JAVA百科s2: 0.023

But in IE8 it is another story:

LOG: removeAddress1: 0.203
LOG: removeAddress2: 0.547

The form in question is a 20-person in put form with first name, last name, and 5 address fields. I've also put in a drop down for selecting other addresses already existing in the form (.primary_address). This code is removing an address from the primary address select boxes.

I'm trying to nail down why this is taking so long, and the only thing which stands out is the option[value=????] section. This was the most practical way to find the elements in question, so I ran with it. Is there something about these two selectors which is causing IE to lose its lunch?


The option element is always temperamental. Perhaps it's simpler to just get all the SELECT elements and then simply query their values. The selected OPTION always will give its value property to the SELECT as well. So:

jQuery('.add_driver select.primary_address').filter(function() {
  return $(this).value === pk;
});

jQuery('.add_driver select.primary_address[value='+pk+']');

Maybe one of those will be faster - not sure if the second will work.


You can likely speed this up a lot by breaking down your uber-selector string.

To start, begin with an id, or even better a cached element. Then get your select elements using .children(). Instead of using the :has selector use .has(). Methods are generally faster than complex selector syntax because jQ doesn't have to parts a string to figure out what you mean. Then, as Rafael said, you can skip the :selected and just look at the value of the matched select's.

formElem = document.getElementById('formId');
jQuery('.add_driver', formElem)
    .children('select.primary_address')
        .has('[value=' + pk + ']')
        .each(...);

Passing formElem as the second arg uses it as the context for the search so jQ doesn't have to start at the root.

To .remove() the elements either cache the jQuery object from above or chain it on after the .each() so you don't have to reselect everything again.


Maybe precompute $('formId .add_driver select') outside of the removeAddress function, then reuse that so the removeAddress() doesn't have to enumerate so many elements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜