admin管理员组文章数量:1332980
I have a button in my page that's looping a series of DIVs and editing them (appending text mostly, nothing serious), The thing is, the number of DIVs is changing by the user (The user can add or remove them freely),
I'm looping the DIVs via jQuery $.each function:
var DomToEdit = $('.divs_to_edit');
$.each(DomToEdit, function() { $(this).append('text'); ... });
the variable DomToEdit contains somewhat unlimited number of divs, and then I refer to them via the $.each function.
Sometimes while doing the $.each loop the user gets to wait for a couple of secons, and in worse cases the browser is crashing
Is there a way to prevent this? Maybe having the loop "sleep" after 50 DIVs?
Thanks
EDIT: I didn't use the same ID, sorry - it was a flaw in my explanation. I use the same class. :)
I have a button in my page that's looping a series of DIVs and editing them (appending text mostly, nothing serious), The thing is, the number of DIVs is changing by the user (The user can add or remove them freely),
I'm looping the DIVs via jQuery $.each function:
var DomToEdit = $('.divs_to_edit');
$.each(DomToEdit, function() { $(this).append('text'); ... });
the variable DomToEdit contains somewhat unlimited number of divs, and then I refer to them via the $.each function.
Sometimes while doing the $.each loop the user gets to wait for a couple of secons, and in worse cases the browser is crashing
Is there a way to prevent this? Maybe having the loop "sleep" after 50 DIVs?
Thanks
EDIT: I didn't use the same ID, sorry - it was a flaw in my explanation. I use the same class. :)
Share Improve this question edited Feb 11, 2012 at 6:05 Tomer Gal asked Feb 10, 2012 at 16:13 Tomer GalTomer Gal 96913 silver badges21 bronze badges 4- 1 I hope you don't have divs with the same IDs. – MacMac Commented Feb 10, 2012 at 16:16
- It seems strange that you have multiple elements with the same ID, you should put a class instead of divs_to_edit then use $('.divs_to_edit'); this may improve performance – Luc Laverdure Commented Feb 10, 2012 at 16:16
- Should probably look at improving your markup first, if there are a lot of elements. – O.O Commented Feb 10, 2012 at 16:18
-
Wouldn't
DomToEdit.each(function(){})
be better? – gen_Eric Commented Feb 10, 2012 at 16:19
6 Answers
Reset to default 3The first argument of the function in the .each
handler is the index of the current element. you can simply add a check before it, and return false
to stop the loop.
$.each(DomToEdit, function(i) { // or DomToEdit.each(function() {
if (i === 50) return false;
..
DomToEdit
is a jQuery object, so $.each(DomToEdit, fn)
and DomToEdit.each(fn)
are equivalent.
A more effective method is to cut off the elements, using .slice(0, 50)
.
DomToEdit.slice(0, 50).each( function(i) {
..
Add a timer which will execute append 50 div's every 5 seconds and works thru the array of div until it finishes iterating all div.
Below code works on 50 div every 5 seconds.
var DomToEdit = $('#divs_to_edit');
var timer = setInterval( function () { //<-- Create a Timer
$.each(DomToEdit, function(index) { //<-- Iterate thru divs
if (index == 50) return; //<-- Return on 50 for later
$(this).append('text');
});
DomToEdit = DomToEdit.slice(0, 50); //<-- Slice the processed div's
// Clear timer when all elements are processed.
if (DomToEdit.length == 0) {
clearInterval(timer);
}
}, 5000); // <-- Do the steps on every 5 secs
Whenever I think that code can potentially cause a crash, I'll create a self-decementing breaker
variable that breaks out of a loop after a certain number of loop cycles.
var breaker = 100;
while(true) {
breaker--;if(breaker<0){console.log("Oh snap batman");break;}
console.log("CRASH");
}
The method could execute alternative code that works around the crash as well. Usually, I just try to fix the code somehow ;)
You could setTimeout
to 0 in order to queue the processing of each element into the execution stack (0 makes it just queue without delay):
$.each(DomToEdit, function() {
var elem = $(this);
setTimeout(function() { elem.append('text'); }, 0);
});
You could queue the tasks and then execute tasks in batches of X every Y milliseconds:
var queue = [];
$.each(DomToEdit, function () {
queue.push( $.proxy( function () {
$(this).append('text');
}, this ));
});
window.setInterval( function(){
var l = 100;
while( queue.length && l-- ) { //Keep executing tasks until there
//is no more or maximum amount of tasks
//executed for this batch is executed
queue.shift()();
}
}, 50 );
The real fix is of course carefully review what you are doing and fix that. $('#divs_to_edit')
always returns a single element max so .each
doesn't make much sense here for example...
It's possible with an extremely large number of elements, that it would actually be less processor intensive to pull the entire container element as a string and run a Javascript .replace()
on it and replace the entire container, than looping through hundreds of thousands of elements?
本文标签: jqueryHow to stop long javascript loops from crashing the browserStack Overflow
版权声明:本文标题:jquery - How to stop long javascript loops from crashing the browser? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742344285a2457209.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论