jquery如何在(几乎)准确的时间内始终如一地执行动画功能?

dcl*_*901 6 javascript jquery animation loops

我尝试使用循环和setInterval函数编写自己的动画函数来动画数字的向上和向下计数.在Chrome中,它似乎运行得很好,但在Firefox上,它看起来很滞后,并且需要比规定的完成时间更长的时间.

我假设不同之处在于两个浏览器快速执行Javascript的能力,但在遇到这个问题之后,我对jQuery如何在时间上如此一致感到好奇,因为它显然没有使用这个过程我以为会这样.

编辑:这是我的代码,因为它被请求:

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';
}
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*all 2

我在您的代码中没有看到任何检查时间差异的内容。在大多数库(jQuery、MooTools 等)中,动画会根据时间进行调整。

jQuery 使用一种方法step来确定效果的下一个值。要查看该函数,请打开 jQuery 的开发(非压缩)版本并搜索jQuery.fx.prototype. 该代码块包含该step方法。

假设您想要告诉一个元素从一个位置移动到另一个位置。看起来您的代码将迭代,直到完成固定数量的动画。所以你严格控制迭代次数而不是时间。浏览器经常滞后。有人可能在他们的机器上运行各种垃圾,这会减慢你的执行速度。然后动画的总执行时间将比预期的长,并且动画本身将“不稳定”。

所以,你应该做的是严格控制时间,而不是试图强制执行均匀的步骤。每次“单步执行”动画时,您都应该考虑动画开始的时间、动画必须完成的总时间以及已经过去的时间。这样你就可以知道动画应该在哪里。因此,如果您想在 10 秒内(线性)将一个元素从位置 100 移动到 200,并且我们处于 7.5 秒,您知道该位置为 175。然后,一旦时间等于或超过您设置的完整 10 秒将其设置为 200 并终止循环。

由于 jQuery 代码使用的缓动效果以及所有内部挂钩和回调,阅读起来会有点困难。但这个想法非常简单。