Using select2 plugin (/)
This searches through all option values for the $selectstring variable and then selects the ones found. If its searching over 200 option values it takes about 5-6 seconds...im trying to reduce this.
Is there a way to speed up my search element for containing-string code?
Is it true that using a for loop instead of $.each would be better performance?
jquery:
$('#selectbutton').click(function() {
var selectstring = $('#selectstring').val();
if (!selectstring.trim())
return false;
stringVal.push($('#projadd\\[\\]').val());
$('#projadd\\[\\]').find('option').each(function(){
if($(this).is(':contains(' + selectstring + ')')){
stringVal.push($(this).val());
}
$('#projadd\\[\\]').val(stringVal).trigger("change");
});
$('#selectstring').val('');
});
Using select2 plugin (http://select2.github.io/select2/)
This searches through all option values for the $selectstring variable and then selects the ones found. If its searching over 200 option values it takes about 5-6 seconds...im trying to reduce this.
Is there a way to speed up my search element for containing-string code?
Is it true that using a for loop instead of $.each would be better performance?
jquery:
$('#selectbutton').click(function() {
var selectstring = $('#selectstring').val();
if (!selectstring.trim())
return false;
stringVal.push($('#projadd\\[\\]').val());
$('#projadd\\[\\]').find('option').each(function(){
if($(this).is(':contains(' + selectstring + ')')){
stringVal.push($(this).val());
}
$('#projadd\\[\\]').val(stringVal).trigger("change");
});
$('#selectstring').val('');
});
.val()
? Looks like you are trying to add to a string, but that is not what .push()
does. There is a lot wrong with your code.
– Sverri M. Olsen
Commented
Mar 17, 2015 at 15:22
.val()
on a multi select mean it will select multiple options : jsfiddle/cunr5u2t
– Karl-André Gagnon
Commented
Mar 17, 2015 at 15:31
The problem here is not the .each()
but your code in general. You are creating a lot of jQuery object when there is no need to it. You are also assigning a value to an element multiple times in the each when it should be outside of it.
Try avoiding jQuery when you can easily do it vanilla. Also try avoiding :contain
since it is a costly selector.
Go with a code that look like that :
$('#selectbutton').click(function() {
var selectstring = document.getElementById('selectstring').value; //Reduced the number of function call and doesn't create a jQuery object.
if (!selectstring.trim())
return false;
var $projadd = $('#projadd\\[\\]');//You use it more than 1 time? Cache it
stringVal.push($projadd.val());
$projadd.find('option').each(function(){
if(this.textContent.indexOf(selectstring) > -1){ //Don't use :contains, use native Javascript methods
stringVal.push(this.value); //Do not create jQuery object, acces value property. Accessing properties is always faster than calling a function.
}
});
$projadd.val(stringVal).trigger("change"); //Move it out of the .each, you only need to set the value once.
document.getElementById('selectstring').value = ''; //Same reason as above.
});
First of all try reducing the numbers of object fetching calls inside the loop.
then the baseline is this:
For loop
is faster.
You may get at least 40% better performance using for loop
with assigning values inside the loop.
Please see these online tests : http://jsperf./for-vs-foreach/75
Note: If you care about performance, first create a model of your script
then test it in various conditions using some framework, jsperf for eg.
Is it true that using a for loop instead of $.each would be better performance?
Yes, but it's small part of time spent in your loop.
Is there a way to speed up my search element for containing-string code?
Yes, you can use searching in element textContent without jQuery.
$('#projadd\\[\\]').find('option').each(function(){
if(this.textContent.indexOf(selectstring) !== -1){
stringVal.push($(this).val());
}
$('#projadd\\[\\]').val(stringVal).trigger("change");
});
Anyway, this code is quite buggy because eg. .val(stringVal)
sets element value to array (is it intended? I don't think so).