2013-09-27 175 views
10

Khi lặp qua bộ sưu tập lớn và thêm nó vào DOM, DOM chỉ làm mới sau khi tất cả các mục đã được nối. Tại sao không cập nhật DOM sau mỗi cuộc gọi append()? Tôi có thể buộc DOM làm mới sau mỗi lần chắp thêm (hoặc có thể sau mỗi số lần nối tiếp)?jQuery chắp thêm vào vòng lặp - DOM không cập nhật cho đến khi kết thúc

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

Link to jsfiddle

LƯU Ý: Tôi hiểu rằng hiệu suất tốt hơn (tránh DOM reflow) có thể đạt được bằng cách thêm tất cả các yếu tố để một biến địa phương, và sau đó phụ thêm rằng biến vào DOM. Nhưng tôi muốn các phần tử n đầu tiên hiển thị trên màn hình, sau đó là n tiếp theo, v.v. cho đến khi tất cả các phần tử được hiển thị.

+0

Tôi nghĩ là có, nhưng tôi nghĩ nó đóng băng giao diện người dùng trong khi thực hiện vòng lặp lớn, vì vậy dường như nó đã làm tất cả cùng một lúc nhưng không. –

Trả lời

10

Hầu hết tất cả mọi thứ trong các điểm dừng trình duyệt trong khi Javascript đang chạy. Điều này bao gồm ví dụ về hiển thị DOM, xử lý sự kiện, hoạt ảnh.

Cách duy nhất để hiển thị DOM là kết thúc Javascript. Bạn có thể sử dụng phương pháp setTimeout để bắt đầu mã một lần nữa sau khi cập nhật:

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

Demo: http://jsfiddle.net/Uf4N6/

+0

Giải thích và ví dụ tuyệt vời, cảm ơn! – Domenic

-3

Nếu đó là thực sự những gì bạn muốn làm ...

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

bạn cần phải cung cấp lại quyền kiểm soát cho trình duyệt mỗi một lần trong một thời gian:

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

Nói chung, xin đừng chạm vào DOM quá nhiều lần. Nó là một kẻ giết người hiệu suất như bạn đã quan sát.

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

Bằng cách này, bạn chỉ chạm DOM một lần!

Một cách khác là sử dụng mảng.

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

LƯU Ý: Tôi hiểu rằng hiệu suất tốt hơn (tránh DOM reflow) có thể đạt được bằng cách thêm tất cả các phần tử vào biến cục bộ, sau đó thêm biến đó vào DOM. Nhưng tôi muốn các phần tử n đầu tiên hiển thị trên màn hình, sau đó là n tiếp theo, v.v. cho đến khi tất cả các phần tử được hiển thị. – Domenic

+0

O có. Xin lỗi tôi đã không giải quyết nhu cầu của bạn. – Blaise