2013-09-27 5 views
10

При переходе по большой коллекции и добавлении ее в DOM DOM обновляется только после того, как все элементы были добавлены. Почему обновление DOM после каждого звонка append()? Могу ли я заставить DOM обновляться после каждого добавления (или, может быть, после каждого n числа добавлений)?jQuery append in loop - DOM не обновляется до конца

var i = 0; 
for (i=0; i<5000; i++) { 
    $('#collection').append('<li>Line Item</li>'); 
} 

Link to jsfiddle

Примечание: Я понимаю, что более высокую производительность (избегая DOM оплавления) может быть достигнуто путем добавления всех элементов локальной переменной, а затем добавив эту переменную в DOM. Но я хочу, чтобы первые n элементов отображались на экране, затем в следующем n и т. Д., Пока все элементы не будут визуализированы.

+0

0 Я думаю, что это так, но я думаю, что он замораживает пользовательский интерфейс при выполнении большой петли, поэтому кажется, что он сделал все сразу, но это не так. –

ответ

10

Большинство все в остановках браузера пока работает Javascript. Сюда входит, например, рендеринг DOM, обработка событий, анимация изображения.

Единственный способ заставить DOM быть визуализированным - это закончить Javascript. Вы можете использовать метод setTimeout для запуска кода снова после обновления:

var i = 0; 

function appendSomeItems() { 
    for (var j=0; j<50; i++, j++) { 
    $('#collection').append('<li>Line Item</li>'); 
    } 
    if (i < 5000) window.setTimeout(appendSomeItems, 0); 
} 

appendSomeItems(); 

Демо: http://jsfiddle.net/Uf4N6/

+0

Отличное объяснение и пример, спасибо! – Domenic

-3

Если это действительно то, что вы хотите сделать ...

var i = 0; 
for (i=0; i<5000; i++) { 
    setTimeout(function() { 
     $('#collection').append('<li>Line Item</li>'); 
    }, 0); 
} 
2

вам нужно вернуть управление браузером каждый раз в то время:

var current = 0 


    function draw() { 
     var next = current + 10 
     for(var i = current; i < next; i++) { 
      $('#collection').append('<li>Line Item</li>'); 
     } 
     current = next 
     setTimeout(draw, 50); 
    } 

draw(); 
-2

Вообще, пожалуйста, не трогайте DOM слишком много раз. Это убийца, как вы уже заметили.

var result=""; 
for (i=0; i<5000; i++) { 
    result+='<li>Line Item</li>'; 
} 
$('#collection').append(result); 

Таким образом, вы коснитесь DOM только один раз!

Альтернативный способ использования массива.

var result=[]; 
for (i=0; i<5000; i++) { 
    result.push('<li>Line Item</li>'); 
} 
$('#collection').append(result.join("")); 
+0

ПРИМЕЧАНИЕ. Я понимаю, что более высокая производительность (исключая DOM reflow) может быть достигнута путем добавления всех элементов к локальной переменной, а затем добавления этой переменной в DOM. Но я хочу, чтобы первые n элементов отображались на экране, затем в следующем n и т. Д., Пока все элементы не будут визуализированы. – Domenic

+0

O да. Извините, я не обращал внимания на ваши потребности. – Blaise

Смежные вопросы