2012-05-25 2 views
7

Ich versuche, den folgenden Code zu verwenden Zahl in einem Textfeld zu erhöhenWarum kann Jquery die Nummer nicht genau animieren?

// Animate the element's value from 0 to 1100000: 
$({someValue: 0}).animate({someValue: 1100000}, { 
    duration: 1000, 
    step: function() { // called on every step 
     // Update the element's text with value: 
     $('#counterx').text(Math.floor(this.someValue+1)); 
    } 
}); 

es ist mit kleinen Zahlen wie von 0 bis 100 arbeiten, aber wenn es um die große Zahl wie in dem genannten Code, es gibt nicht die Zielnummer, es animiert zu Zahlen wie 1099933 oder 1099610 oder ..... und jedes Mal, wenn es sich ändert.

also wie kann ich es animieren, um die nummer ich spezifiziere?

+1

was 'someValue'? Ist das eine gültige CSS-Eigenschaft? Post Sie Markup. – thecodeparadox

+0

Nein, es ist nur ein Hash-Objekt. –

+0

Können Sie das Markup posten? – Jashwant

Antwort

15

Ich habe das gleiche Problem. Der Grund dafür ist, dass die Funktion animate eine mathematische Formel verwendet, die zeitbasiert ist. Sie bemerken das nicht wirklich, wenn Sie etwas basierend auf css animieren, weil nahe genug in Pixeln gut genug ist. Es nähert sich dem Endwert, ist aber möglicherweise nicht immer genau der Endwert. Die Lösung besteht darin, das Ereignis complete zu verwenden, um den letzten Wert festzulegen.

Hier ist, was Sie tun müssen:

function animateNumber(ele,no,stepTime){ 
 
$({someValue: 0}).animate({someValue: no}, { 
 
     duration: stepTime, 
 
     step: function() { // called on every step. Update the element's text with value: 
 
      ele.text(Math.floor(this.someValue+1)); 
 
     }, 
 
     complete : function(){ 
 
      ele.text(no); 
 
     } 
 
}); 
 
} 
 

 
animateNumber($('#counterx'),100,10000); 
 
animateNumber($('#countery'),100,1000)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
counterx(slow): <span id=counterx>--</span> 
 
<br/> 
 
countery(fast): <span id=countery>--</span>

+1

Ist das nicht eine der kompliziertesten Methoden? – frenchie

+0

Wer sagt dir diese Geheimnisse? : O Btw stimme ich @Frenchie – Jashwant

+1

Nein. Ich abstrahiert dies auf seine eigene Methode und ich denke eigentlich, es ist ziemlich sauber. Viel besser als mit 'setTimeout' und selbst mit der Animation. –

3

Animate nicht ausgelegt ist, einen Zähler als Text zu erhöhen (obwohl es durch Zufall arbeiten kann, die mit jeder ändern könnte neue Version von jQuery), es ist entworfen, um eine oder mehrere CSS-Eigenschaften zu animieren. Sie sollten stattdessen setInterval verwenden.

http://jsfiddle.net/jbabey/mKa5r/

var num = 0; 

var interval = setInterval(function() { 
    document.getElementById('result').innerHTML = num; 
    num++; 

    if (num === 100) { 
     clearInterval(interval);    
    } 
}, 100);​ 
+0

Das ist nicht wahr. Es funktioniert. –

+0

@AmirRaminfar also Sie downvote eine einfache und effektive Lösung und schlagen einen komplizierten vor? – jbabey

+0

+1 für myside nur zu kompensieren und für richtige Antwort :) – Jashwant

3

1) Javascript ist eine Single-Threaded-Anwendung. Timeouts und Animationen schieben das Ereignis NUR auf der Grundlage einer idealen Stapelreihenfolge an das Ende des Stapels. Ein langer laufender Abschnitt des Skripts kann dazu führen, dass die eigentliche Auslösezeit dieses Ereignisses weit über die Genauigkeit hinausgeht, nach der Sie suchen.

2) Die Animation approximiert, um wie viel erhöht werden soll, und bei größeren Zahlen ist die Auflösung sehr ungenau.

3) jQuery hat nur einen Animationspuffer. Es kann zu ernsthaften Renderproblemen kommen, wenn Sie mehr als einen "Counter" mit Animation aufrufen. Stellen Sie sicher, dass Sie die vorherige Animation anhalten, bevor Sie Änderungen vornehmen.

4) Auch bei einer Zeitüberschreitung von 0 können Sie die tatsächliche Verzögerung von ~ 15 erwarten. Auch wenn das der einzige "Thread" ist, den Sie ausgeführt haben.

Lösung:

take a snapshot of the DTG 
set your interval to something within the human experience, say ~200 
on each interval, check how much time has passed from the original DTG 
set your text field to that delta number. 
stop the interval with the original DTG + "your target number" > the new DTG 
+0

Ich bin verwirrt, was Sie hier beantworten? –

+0

Es gibt technische Aspekte von JavaScript (die jQuery zum Ausführen seiner Animation verwendet), die die in dieser Frage erwähnte Ungenauigkeit verursachen. Es gibt auch bekannte Probleme beim Ausführen mehrerer Animationen zur gleichen Zeit (z. B. Ausführen einer .show (1000); im selben Zeitrahmen wie das Ausführen einer Animation für dasselbe Objekt), die für gelegentliche Benutzer von Animationen möglicherweise nicht gut bekannt sind. Meine Antwort ist die genaueste Art zu wissen, wie viel Zeit zwischen den Intervallen verstrichen ist, da Timeouts selbst single-threaded sind und einer programmatischen Verzögerung unterliegen. Etwas, das die Lösung mit "vollständig" verbindet: –

2

Hier ist eine Lösung, die nicht .animate() nicht verwendet.

DEMO:http://jsfiddle.net/czbAy/4/

Es ist nur eine lineare Änderung; Sie haben nicht die Lockerung Optionen, wenn Sie das wollten.

var counterx = $('#counterx'), // cache the DOM selection! :) 
    i = 0, 
    n = 1100000, 
    dur = 1000, // 1 second 
    int = 13, 
    s = Math.round(n/(dur/int)); 

var id = setInterval(function() { 
    counterx.text(i += s); 
    if (i >= n) { 
     clearInterval(id); 
     counterx.text(n); 
    } 
}, int); 
0

Hier ist ein jQuery-Plugin Zahlen zuverlässig zu animieren, verwendet ut den kompletten Rückruf, um die korrekte endgültige Zahl einzustellen, sobald die Animation beendet hat:

https://github.com/kajic/jquery-animateNumber