Frage

Ich habe ein Element auf meiner Seite habe, dass ich auf Zuwachs von Zeit zu Zeit möchte:

<p class="count">28</p>

In meinem Javascript habe ich ein Intervall, das ausgeführt wird, sobald alle 5 Sekunden und asynchron die neue packt (höher) Nummer vom Server. Dies funktioniert etwas entlang der Linien eines Zählers.

setInterval(function(){
  $.post("getcount.php", function(num){
    latestNum = num;
  });
}, 5000);

Wenn die asynchrone Anforderung nach unten zieht die Nummer 56, würde Ich mag den Absatz Textänderung auf 56 von 28 zu sehen, die zeigen, viele (oder die meisten) oder die Zwischenprodukte, während er-Schritten. Was ich zur Zeit tue, ist ein anderes Intervall setzt immer wieder den Absatztext zu überprüfen und die lokalen Variable. Wenn der Absatztext niedriger als der Variablenwert ist, erhöht er es von 1. Es tut dies jeder ein halbes Sekunde.

setInterval(function(){
  currNum = Number( $(".count").text() );
  if (currNum < latestNum)
    $(".count").text( currNum + 1 );
}, 50);

Meine Frage ist: Gibt es einen besseren Weg, dies zu tun, ohne ein Intervall ständig mit Laufen? Ist das animierte inkrementierende etwas, das ich aus der Antwort von einer asynchronen Anforderung aufrufen kann, und dann haben sie aufhören, sobald die beiden Zahlen in Wert erfüllt haben? Ich sollte auch beachten Sie, dass die Möglichkeit besteht, dass die nächste Anforderung stattfinden wird, bevor die beiden Zahlen sind im Wert in Einklang gebracht werden.

Wie würde die kollektive Sie das tun?

War es hilfreich?

Lösung

Hier ist meine Antwort -. Eigentlich zwei Antworten
Stepping linear auf den Zielwert mit einem festen Intervall Risiken nicht immer dorthin zu gelangen.
So habe ich eine andere Lösung zu versehen, die den Unterschied jedesmal halbiert, wird es viel schneller auch für große Unterschiede.
Beide Beispiele können auch abzulaufen.

$( function() {

    var tRef,
        counter = $( '#counter' );
        target  = $( '#target' );

    /*
     * A function that eases towards its target
     */
    function convergeEasing( target ) {
        clearTimeout( tRef );
        target = parseInt( target );
        var current = parseInt( counter.html() );
        var diff = target - current;
        if( diff ) {
            var rounder = diff > 0 ? Math.ceil : Math.floor;
            current += rounder( diff/2 );
            counter.html( current );
            tRef = setTimeout( function() {
                convergeEasing( target );
            }, 250 );
        }
    }

    /*
     * A function that plods towards its target
     */
    function convergeLinear( target ) {
        clearTimeout( tRef );
        target = parseInt( target );
        var current = parseInt( counter.html() );
        var diff = target - current;
        if( diff ) {
            current += diff > 0 ? 1 : -1;
            counter.html( current );
            tRef = setTimeout( function() {
                convergeLinear( target );
            }, 250 );
        }
    }

    /*
     * I've mocked your ajax request up here for demo purposes
     * using the linear way as per your question
     */
    setInterval( function(){
        var n = Math.round( Math.random()*1000 );
        target.html( n );
        convergeLinear( n );
    }, 5000 );

});

<div id="target">20</div>
<div id="counter">20</div>

Ich nehme an, die Lockerung Strategie Funktion sein könnte, die in eher als die beiden Funktionen übergeben wird dupliziert viel von ihrem Code

Andere Tipps

Korrigiert Antwort:

Zu den commen: habe erkannt, dass ich ... noch danke

!
var interval = setInterval(function(){
  currNum = Number( $(".count").text() );
  if (currNum < latestNum) {
    $(".count").text( currNum + 1 );
  } else {
    setTimeOut(function() { clearInterval(interval) }, 0);
  }
}, 50);

Das spart das Intervall in einer Variablen und ruft dann clearInterval das Intervall zu stoppen. setTimeOut wird, da sonst das Intervall benötigt würden gelöscht werden, während es ausgeführt wird.

Erste Antwort:

Warum nicht combinding die beiden Funktionen, das heißt:.

setInterval(function(){
  $.post("getcount.php", function(num){
    latestNum = num;
    if (currNum < latestNum) {
        currNum = latestNum;
        $(".count").text( currNum );
    }
  });
}, 5000);

Dies würde das Update jede halbe Sekunde verhindern.

Aufbauend auf Obalix Antwort, würde ich empfehlen, den 5-Sekunden-Intervall-Trigger mit dem kleineren Intervall.

var interval = null, currNum = null;
setInterval(function(){
  $.post("getcount.php", function(num){
    latestNum = num;
    if (currNum === null)
        currNum = Number( $(".count").text() ); // should only execute once
    if (currNum < latestNum && interval === null)
        interval = setInterval(ObalixFunction, 50);
  });
}, 5000);

und modify

function ObalixFunction() {
    if (currNum < latestNum) {
        // increment the currNum variable too so we don't have to keep parsing it
        $(".count").text( ++currNum ); 
    } else {
        setTimeOut(function() { clearInterval(interval); interval = null; }, 0);
    }
}

Ich würde das zweite Intervall laichen, wenn das Ergebnis empfangen wurde und es beenden, wenn der Zielwert erreicht wurde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top