5

Podczas metody, która działa przez 10 sekund w celu dodania niektórych elementów do html, animowany gif nie porusza się wcale, dając wrażenie, że strona utknęła. Jakikolwiek sposób obejścia tego.Animowany obraz nie porusza się podczas długiego wywołania metody javascript

Przykładowy kod:

 
    $('#button).click(function() { 
     showAnimatedGif(); 
     longRunningMethod();  
     hideAnimatedGif(); 
    }); 

Jednym ze sposobów na to jest do rozpadu długo metoda działa w wielu etapach i animowanie ten sposób, ale potem trzeba napisać kod w ten sposób dla każdego długiego sposobu jazdy.

Zastanawiasz się, czy jest jeszcze coś innego?

+0

[Nie rób tego wtedy] (http://www.jargon.net/jargonfile/d/Dontdothatthen.html). Wiesz, że JavaScript nie jest wielowątkowy, prawda? –

+0

Wiem o tym, ale muszą istnieć sposoby, aby to osiągnąć. – mrjohn

+0

Co robi 'showAnimatedGif()'? Co robi 'longRunningMethod()'? Czy możesz dodać więcej kodu? – karim79

Odpowiedz

6

Jedynym sposobem na zapewnienie, że animacja rzeczywiście występuje, jest okresowe wyświetlanie przeglądarki przez użytkownika longRunningMethod. Często zdarza się, że wątek wyświetlania interfejsu użytkownika blokuje się w wątku JavaScript, więc zmiany wprowadzone w modelu DOM są wyświetlane dopiero po następnym dostarczeniu wątku JavaScript. Możesz uzyskać wywołanie setTimeout z limitem czasu wynoszącym 0 (który będzie dłuższy niż 0ms   — oczywiście   — dla większości implementacji przeglądarek, wiele z nich ma wartość co najmniej 4ms, a może nawet 10ms).

Przykład: Oto skrypt, który dodaje 500 DIV, ale daje przeglądarka ma okazję pokazać się w toku lub (zazwyczaj) animowania czegokolwiek:

jQuery(function($) { 

    $("#btnGo").click(function() { 
    var n; 

    display("Loading..."); 

    for (n = 0; n < 500; ++n) { 
     $("<div/>").html("Div #" + n).appendTo(document.body); 
    } 

    display("Done loading"); 

    function display(msg) { 
     $("<p/>").html(msg).appendTo(document.body); 
    } 
    }); 

});​ 

Live example * Example with spinner graphic

jak można widzisz, nigdy się nie poddaje, a więc po kliknięciu przycisku strona zamiera na chwilę, a następnie pojawia się wszystkich 500 elementów div i komunikatów.

Kontrast z tym drugim końcu spektrum, co daje między każdy div:

jQuery(function($) { 

    $("#btnGo").click(function() { 
    display("Loading..."); 

    addDivs(0, 500, function() { 
     display("Done loading"); 
    }); 

    function addDivs(current, max, callback) { 
     if (current < max) { 
     $("<div/>").html("Div #" + current).appendTo(document.body); 
     setTimeout(function() { 
      addDivs(current + 1, max, callback); 
     }, 0); 
     } 
     else { 
     callback(); 
     } 
    } 

    function display(msg) { 
     $("<p/>").html(msg).appendTo(document.body); 
    } 
    }); 

});​ 

Live example * Example with spinner graphic

Ponieważ plony, można zobaczyć w toku.

Możesz zauważyć, że drugi skrypt zajmuje więcej czasu, prawdopodobnie dłużej, w czasie rzeczywistym, aby osiągnąć ten sam rezultat. Dzieje się tak, ponieważ plony wymagają czasu, podobnie jak przeglądarka aktualizująca wyświetlacz. W praktyce będziesz chciał znaleźć równowagę między pierwszym przykładem a drugim, co daje wystarczająco często, aby pokazać postęp, ale nie tak często, że proces ten zajmuje niepotrzebnie dużo czasu.

+0

Jakie jest dokładne wywołanie funkcji setTimeout? – mrjohn

+0

@mrjohn: Dodano przykład zi bez. –

+0

Interesujący punkt dotyczący znalezienia właściwej równowagi. Zastanawiam się, czy jest możliwe, aby wykonać wydajność przeglądarki przed plonowaniem, aby uzyskać najlepszy wynik. Rodzaj podobnego FPS w grafice. –

0

Jeśli twoja metoda długiego działania wykonuje synchroniczne wywołanie ajax. Użyj opcji asynchronicznej w metodzie otwartej.

xmlHttp.open('POST', ajaxurl, true); 

Pozwoli to na obracanie się obracającej się grafiki.

Powiązane problemy