2013-09-27 13 views
10

Po zapętleniu dużej kolekcji i dołączeniu jej do DOM, DOM odświeża się dopiero po dołączeniu wszystkich elementów. Dlaczego aktualizacja DOM po każdej rozmowie append() nie jest aktualizowana? Czy mogę wymusić odświeżenie DOM po każdym dołączeniu (lub po każdej n liczbie załączeń)?jQuery dołącz do pętli - DOM nie aktualizuje się do końca

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

Link to jsfiddle

UWAGA: Rozumiem, że lepsza wydajność (unikanie DOM reflow) można osiągnąć poprzez dołączenie wszystkich elementów do zmiennej lokalnej, a następnie dodanie tej zmiennej do DOM. Ale chcę, aby pierwsze n elementów wyświetlało się na ekranie, następnie następne n, itd., Aż wszystkie elementy zostaną renderowane.

+0

Myślę, że tak, ale myślę, że zamarza interfejs podczas wykonywania wielkiej pętli, więc wydaje się, że zrobił to wszystko naraz, ale tak się nie stało. –

Odpowiedz

10

Większość wszystko przystanków przeglądarce podczas działania Javascript. Obejmuje to na przykład renderowanie DOM, obsługę zdarzeń, animację obrazu.

Jedynym sposobem na wyrenderowanie DOM jest zakończenie JavaScript. Można użyć metody setTimeout zacząć kod ponownie po aktualizacji:

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

Świetne wyjaśnienie i przykład, dzięki! – Domenic

-3

Jeśli to jest naprawdę to, co chcesz zrobić ...

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

trzeba oddać kontrolę do przeglądarki raz na jakiś czas:

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

Generalnie, proszę nie dotykać DOM zbyt wiele razy. To zabójca wydajności, jak już zauważyliście.

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

W ten sposób dotkniesz DOM tylko raz!

Alternatywnym sposobem jest użycie tablicy.

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

UWAGA: Rozumiem, że lepszą wydajność (unikanie zmiany przepływu DOM) można osiągnąć, dołączając wszystkie elementy do zmiennej lokalnej, a następnie dołączając tę ​​zmienną do DOM. Ale chcę, aby pierwsze n elementów wyświetlało się na ekranie, następnie następne n, itd., Aż wszystkie elementy zostaną renderowane. – Domenic

+0

O tak. Przepraszam, że nie spełniłem twoich potrzeb. – Blaise

Powiązane problemy