How does jquery sequentially perform animation functions in (almost) exact time?

I tried writing my own animation function to animate the counting of numbers up and down using loops and the setInterval function. It works very well in Chrome, but on Firefox it looks laggy and takes much longer than the set completion time.

I believe the difference lies in the ability of the two browsers to quickly execute Javascript, but when I ran into this problem, I was curious than anything about how jQuery could be so consistent over time, since it apparently doesn't use the process that I thought would be.

Edit: here is my code from the moment it was requested:

 function tallyPrices(){ var current_total = parseFloat( $('.budget span').text() ); var new_total = 0; var animation_options = { iterationTime : 10, totalTime : 500 } $('#chosen-items li').each( function(){ if( $(this).attr('data_price') !== 'n/a' ){ new_total += parseFloat( $(this).attr('data_price') ); } }); animation_options.difference = current_total - new_total; animation_options.delta = Math.round( Math.abs( animation_options.difference / ( animation_options.totalTime / animation_options.iterationTime ) ) * 100 ) / 100; var timesIterated = 0; var limit = parseFloat( $('.budget span').attr('data_high') ); var animation = setInterval( function(){ timesIterated = priceAnimate( timesIterated, animation_options, $('.budget span'), limit); if(timesIterated === 'done'){ clearInterval(animation); $('.budget span').text( parseFloat( Math.round( new_total * 100 ) / 100 ).toFixed(2) ); } }, animation_options.iterationTime ); } function priceAnimate( count, options, el, limit ){ if( count < ( options.totalTime / options.iterationTime ) && options.difference !== 0){ var current = parseFloat( el.text() ); current = Math.round( current * 100 ) / 100; if( options.difference < 0 ){ el.text( parseFloat( Math.round( (current + options.delta) * 100 ) / 100 ).toFixed(2) ); } else if( options.difference > 0 ){ el.text( parseFloat( Math.round( (current - options.delta) * 100 ) / 100 ).toFixed(2) ); } if( parseFloat( el.text() ) > limit ){ el.parent().addClass('over'); } else { el.parent().removeClass('over'); } count++; return count; } else { return 'done'; } } 
+6
source share
2 answers

I do not see anything in your code, checking the time difference. In most libraries (jQuery, MooTools, etc.) Animation is set up depending on the time.

jQuery uses the step method, which is used to determine the next value for the effect. To look at this feature, open the jQuery version (without compression) and search for jQuery.fx.prototype . This block of code contains the step method.

Suppose you want to say that an element moves from one position to another. It looks like your code will repeat until a fixed number of animations are set. Thus, you strictly observe the number of iterations, not the time. Browsers often lag behind. Someone can run all kinds of garbage on their machine, which will slow down your execution. And then the overall execution of your animation will be longer than expected, and the animation itself will be a "jerk."

So, what you have to do is be strict with time, and not try to apply even steps. Each time you β€œstep” through an animation, you must consider the start time of the animation, the total end time of the animation, and the downtime. With this, you can determine where the animation should be. Therefore, if you want to move an element (linearlly) from position 100 to 200 in 10 seconds, and we are in 7.5 seconds, you know that the position should be 175. Then, as soon as the time is at or for completed 10 seconds, You set this to 200 and kill the loop.

JQuery code will be a little hard to read due to the easing effects it uses and all the internal hooks and callbacks. But the idea is pretty straightforward.

+2
source

Marshall's answer works where you want the animation to run at a given time. Another requirement is to launch something at a specific time, for example, the tactics of the clock. To do this, you use setTimeout and each time you run the function, determine the amount of time until the next "tick" and call setTimeout with this interval (or a slightly longer interval in the case of hours, to make sure that the next update is immediately after the next whole tick).

Using consecutive calls to setTimeout, you can compensate for the drift associated with setInterval.

+1
source

Source: https://habr.com/ru/post/899734/


All Articles