当循环访问大型集合并将其附加到 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);
}