jQuery append in loop - DOM 直到最后才更新

jQuery append in loop - DOM does not update until the end

本文关键字:直到最后 更新 DOM append in loop jQuery      更新时间:2023-09-26

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

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

链接到 jsfiddle

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

浏览器中的大多数内容在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/

您需要每隔

一段时间将控制权交还给浏览器:

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

一般来说,请不要过多地触摸 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(""));

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

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