Reputation: 2674
if you run this page http://jsfiddle.net/atoswchataigner/euX5F in IE7/IE8 you'll get :
Stop running this script? A script on this page is causing Internet Explorer to run slowly. If it continues to run, your computer might become unresponsive.
I basically run all this script to group options in selects.
Do you see better way to do that kind of transformation and get rid of this alert in IE?
Upvotes: 1
Views: 4686
Reputation: 708116
You are running a ton of selector operations, each of which is not very efficient, especially in older browsers.
It's much better to do one selector operation and process all the option values in that one operation. You can do that by building a lookup table for the option values that gives you the appropriate class name. Here's an example. I didn't fill in the entire table as it's a lot of typing (you can type the rest), but here's how it would work.
This should be many times faster than what you had (perhaps more than 100 times faster):
// class names used for various options
var optionClasses = [
"ART - LETTRES - SPECTACLE",
"ECONOMIE",
"ETRANGER"
];
// the number in the option map corresponds to an array index
// in the optionClasses array. This is done to avoid repeating
// the same string over and over
var optionMap = {
'ART - LETTRES - SPECTACLE': 0,
'A la une ALS': 0,
'Cirque' : 0,
'Festival multidisciplinaire': 0,
'Littérature-édition': 0,
'Musique classique': 0,
'Photographie': 0,
'Cinéma': 0,
/* .... */
'ECONOMIE': 1,
'A la une Economie': 1,
/* ... */
'ETRANGER': 2,
'A la une Etranger': 2
/* fill in the rest of the data here */
};
jQuery("select option").each(function() {
if (this.value && this.value in optionMap) {
var clsNum = optionMap[this.value];
$(this).addClass(optionClasses[clsNum]);
}
});
It's simple and should perform many times faster than what you had before. It has one selector operation and then uses a hash table lookup to find the appropriate class name for a given option value.
Upvotes: 3
Reputation: 119887
From what I understand, what your code does is to load options on the second select based on the first select.
Putting such huge amounts of elements on the DOM is intensive. Instead of loading an unusually long line of DOM elements, store the data as arrays and objects instead, and load when necessary. This way, the selects will be blank to begin with.
//storing second options as objects and arrays
var second = {
art : [
{text:'artOption1Text',value:'artOption1Value'},
{text:'artOption2Text',value:'artOption2Value'},
{text:'artOption3Text',value:'artOption3Value'}
...
],
social : [
{text:'socialOption1Text',value:'socialOption1Value'},
{text:'socialOption2Text',value:'socialOption2Value'},
{text:'socialOption3Text',value:'socialOption3Value'}
...
]
...
}
var secondSelect = $('secondselect'); //reference your second select
$('firstselect').on('change',function(){ //on change of first select
var newOptions = second[this.value]; //get the new values
secondSelect.children().remove(); //remove current options
$.each(newOptions,function(index,option){ //add the new options
$('<option>')
.attr('value',option.value)
.text(option.text)
.appendTo(secondSelect);
});
}
Upvotes: 1
Reputation: 13877
These kind of selectors appear to be very slow in firefox too.
I would guess the "[option value='...']" part causes jQuery to scan all of the elements in the entire document looking for matching elements. It does this for each term (part between ','s) in each selector. That's a lot of work.
I had a fiddle and found that in firefox it's much more responsive if I use a method like this:
var options = $("option");
var $XXX = options.filter("[value=VALUE1], [value=VALUE2], [value=VALUE3]");
// etc
What this does is first create a jquery object/collection that contains only the select options, then from there use selectors to filter out the required ones.
Try modifying your code to use this method.
Upvotes: 1