JQuery append в цикле - DOM не обновляется до конца
При переходе по большой коллекции и добавлении ее в DOM, DOM обновляется только после того, как все элементы были добавлены. Почему обновление DOM после каждого вызова append()
? Могу ли я заставить DOM обновляться после каждого добавления (или, может быть, после каждого n числа добавлений)?
var i = 0;
for (i=0; i<5000; i++) {
$('#collection').append('<li>Line Item</li>');
}
Ссылка на jsfiddle
ПРИМЕЧАНИЕ. Я понимаю, что более высокая производительность (исключая DOM reflow) может быть достигнута путем добавления всех элементов к локальной переменной, а затем добавления этой переменной в DOM. Но я хочу, чтобы первые n элементов отображались на экране, затем следующее n и т.д., Пока все элементы не будут отображаться.
Ответы
Ответ 1
Большинство браузеров останавливается во время работы 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/
Ответ 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();
Ответ 3
Как правило, пожалуйста, не нажимайте 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(""));
Ответ 4
Если это действительно то, что вы хотите сделать...
var i = 0;
for (i=0; i<5000; i++) {
setTimeout(function() {
$('#collection').append('<li>Line Item</li>');
}, 0);
}