2012-02-10 29 views
3

我的頁面上有一個按鈕,循環播放一系列的DIV並對它們進行編輯(主要追加文本,沒有什麼嚴重的), 事情是,用戶正在更改DIV的數量(用戶可以自由添加或刪除它們),如何阻止瀏覽器崩潰造成漫長的JavaScript循環?

我通過jQuery $。每個功能循環的DIV:

var DomToEdit = $('.divs_to_edit'); 
$.each(DomToEdit, function() { $(this).append('text'); ... }); 

變量DomToEdit包含的div有些無限數量的,然後我通過$。每個功能是指他們。

有時候一邊做$。每個循環用戶獲取等待一對夫婦secons的,並且在更糟糕的情況下,瀏覽器崩潰

是否有辦法防止這種情況?也許有50個DIV後的循環「睡眠」?

感謝

編輯:我沒有使用相同的標識,對不起 - 這是我的解釋一大敗筆。我使用同一個班級。 :)

+1

我希望你沒有具有相同ID的div。 – MacMac 2012-02-10 16:16:33

+0

看起來很奇怪,你有多個具有相同ID的元素,你應該放一個類而不是divs_to_edit,然後使用$('。divs_to_edit');這可能會提高性能 – 2012-02-10 16:16:52

+0

如果有很多元素,應該首先改善您的標記。 – 2012-02-10 16:18:55

回答

3

處理函數.each中函數的第一個參數是當前元素的索引。您可以簡單地在它之前添加一個檢查,然後return false停止循環。

$.each(DomToEdit, function(i) { // or DomToEdit.each(function() { 
    if (i === 50) return false; 
    .. 

DomToEdit是一個jQuery對象,所以$.each(DomToEdit, fn)DomToEdit.each(fn)是等價的。

更有效的方法是使用.slice(0, 50)來切斷元素。

DomToEdit.slice(0, 50).each(function(i) { 
    .. 
1

每當想起這些代碼可能會導致系統崩潰,我將創建一個自decementing breaker變量一定數量的循環週期後,打破了循環。

var breaker = 100; 
while(true) { 
    breaker--;if(breaker<0){console.log("Oh snap batman");break;} 


    console.log("CRASH"); 

} 

該方法可以執行替代代碼,也可以在崩潰時使用。通常情況下,我只是嘗試以某種方式修改代碼;)

1

你可以setTimeout爲0,以隊列中每個元素的處理到執行棧(0使得它只是排隊無延遲):

$.each(DomToEdit, function() { 
    var elem = $(this); 

    setTimeout(function() { elem.append('text'); }, 0); 
}); 
2

添加一個計時器,它將每5秒執行一次追加50個div,並通過div的數組工作,直到完成迭代所有div爲止。

下面的代碼每5秒在50格上工作。

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 
0

有可能有非常大數量的元素,它實際上是少處理器密集型到整個容器元素拉作爲一個字符串,並在其上運行一個Javascript .replace()和更換整個容器,不是通過循環成千上萬的元素?

1

你可以排隊的任務,然後在X的批次執行任務 每Y個毫秒:

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); 

真正的解決辦法是,當然仔細查看你在做什麼,並解決這個問題。 $('#divs_to_edit')總是返回一個單一的元素,所以.each在這裏沒有多大意義,例如...