16

当循环一个大型集合并将其附加到 DOM 时,DOM 仅在所有项目都附加后才会刷新。为什么每次append()调用后 DOM 不更新?我可以在每次追加后(或者可能在每 n 次追加后)强制 DOM 刷新吗?

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

链接到 jsfiddle

注意:我知道通过将所有元素附加到局部变量,然后将该变量附加到 DOM 可以实现更好的性能(避免 DOM 重排)。但是我希望前 n 个元素在屏幕上呈现,然后是下一个 n,等等,直到所有元素都被呈现。

4

4 回答 4

15

当 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/

于 2013-09-27T19:49:46.817 回答
3

您需要每隔一段时间将控制权交还给浏览器:

    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();
于 2013-09-27T19:49:42.847 回答
-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(""));
于 2013-09-27T19:57:50.813 回答
-4

如果这真的是你想做的...

var i = 0;
for (i=0; i<5000; i++) {
    setTimeout(function() {
        $('#collection').append('<li>Line Item</li>');
    }, 0);
}
于 2013-09-27T19:45:19.977 回答