简体   繁体   中英

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
removeAddress2: 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.

也许在removeAddress函数之外预先计算$('formId .add_driver select'),然后重用该代码,这样removeAddress()不必枚举太多元素。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM