Reputation: 348
I have a script that is taking too long to run and that is causing me This error on ie : a script on this page is causing internet explorer to run slowly.
I have read other threads concerning this error and have learned that there is a way to by pass it by putting a time out after a certain number of iterations.
Can u help me apply a time out on the following function please ?
Basically each time i find a hidden imput of type submit or radio i want to remove and i have a lot of them . Please do not question why do i have a lots of hidden imputs. I did it bc i needed it just help me put a time out please so i wont have the JS error. Thank you
$('input:hidden').each(function(){
var name = $(this).attr('name');
if($("[name='"+name+"']").length >1){
if($(this).attr('type')!=='radio' && $(this).attr('type')!=='submit'){
$(this).remove();
}
}
});
One of the exemples i found : Bypassing IE's long-running script warning using setTimeout
Upvotes: 1
Views: 3843
Reputation: 1792
Try this:
$("[type=hidden]").remove(); // at the place of each loop
It will take a short time to delete all hidden fields.
I hope it will help.
Upvotes: 1
Reputation: 150070
Here's the same code optimised a bit without (yet) using setTimeout()
:
var $hidden = $('input:hidden'),
el;
for (var i = 0; i < $hidden.length; i++) {
el = $hidden[i];
if(el.type!=='radio' && el.type!=='submit'
&& $("[name='" + el.name + "']").length >1) {
$(el).remove();
}
}
Notice that now there is a maximum of three function calls per iteration, whereas the original code had up to ten function calls per iteration. There's no need for, say, $(this).attr('type')
(two function calls) when you can just say this.type
(no function calls).
Also, the .remove()
only happens if three conditions are true, the two type
tests and check for other elements of the same name. Do the type
tests first, because they're quick, and only bother doing the slow check for other elements if the type
part passes. (JS's &&
doesn't evaluate the right-hand operand if the left-hand one is falsy.)
Or with setTimeout()
:
var $hidden = $('input:hidden'),
i = 0,
el;
function doNext() {
if (i < $hidden.length) {
el = $hidden[i];
if(el.type!=='radio' && el.type!=='submit'
&& $("[name='" + el.name + "']").length >1) {
$(el).remove();
}
i++;
setTimeout(doNext, 0);
}
}
doNext();
You could improve either version by changing $("[name='" + el.name + "']")
to specify a specific element type, e.g., if you are only doing inputs use $("input[name='" + el.name + "']")
. Also you could limit by some container, e.g., if those inputs are all in a form or something.
Upvotes: 2
Reputation: 3064
To risk stating the obvious; traversing through the DOM looking for matches to these CSS selectors is what's making your code slow. You can cut down the amount of work it's doing with a few simple tricks:
Are these fields inside a specific element? If so you can narrow the search by including that element in the selector.
e.g:
$('#container input:hidden').each(function(){
...
You can also narrow the number of fields that are checked for the name
attribute
e.g:
if($("#container input[name='"+name+"']").length >1){
I'm also unclear why you're searching again with $("[name='"+name+"']").length >1
once you've found the hidden element. You didn't explain that requirement. If you don't need that then you'll speed this up hugely by taking it out.
$('#container input:hidden').each(function(){
var name = $(this).attr('name');
if($(this).attr('type')!=='radio' && $(this).attr('type')!=='submit'){
$(this).remove();
}
});
If you do need it, and I'd be curious to know why, but the best approach might be to restructure the code so that it only checks the number of inputs for a given name once, and removes them all in one go.
Upvotes: 1
Reputation: 12325
You may want to add input
to your jquery selector to filter out only input tags.
if($("input[name='"+name+"']").length >1){
Upvotes: 2
Reputation: 393
It looks like the example you cited is exactly what you need. I think if you take your code and replace the while
loop in the example (keep the if
statement for checking the batch size), you're basically done. You just need the jQuery version of breaking out of a loop.
Upvotes: 1