2011-07-24 8 views
1

私は、かなり単純なjavascript関数をいくつか使用して、ユーザーのアクションに基づいて上下に移動する数値のアニメーションを作成します。ページには、コールバック内でrecalculateDiscount()を呼び出すスライダがいくつかあります。これらのスライダは、その選択に基づいて数値をアニメーション化します。Javascriptを使用したアニメーターカウンター

var animationTimeout; 

// Recalculate discount 
function recalculateDiscount() { 
    // Get the previous total from global variable 
    var previousDiscount = totalDiscount; 
    // Calculate new total 
    totalDiscount = calculateDiscount().toFixed(0); 
    // Calculate difference 
    var difference = previousDiscount - totalDiscount; 
    // If difference is negative, count up to new total 
    if (difference < 0) { 
     updateDiscount(true, totalDiscount); 
    } 
    // If difference is positive, count down to new total 
    else if (difference > 0) { 
     updateDiscount(false, totalDiscount); 
    } 
} 

function updateDiscount(countUp, newValue) { 
    // Clear previous timeouts 
    clearTimeout(animationTimeout); 
    // Get value of current count 
    var currentValue = parseInt($(".totalSavingsHeader").html().replace("$", "")); 
    // If we've reached desired value, end 
    if (currentValue === newValue) { return; } 
    // If counting up, increase value by one and recursively call with slight delay 
    if (countUp) { 
     $(".totalSavingsHeader").html("$" + (currentValue + 1)); 
     animationTimeout = setTimeout("updateDiscount(" + countUp + "," + totalDiscount + ")", 1); 
    } 
    // Otherwise assume we're counting down, decrease value by one and recursively call with slight delay 
    else { 
     $(".totalSavingsHeader").html("$" + (currentValue - 1)); 
     animationTimeout = setTimeout("updateDiscount(" + countUp + "," + totalDiscount + ")", 1); 
    } 
} 

大部分のスクリプトはうまく動作しますが、いくつか問題があります。まず、古いブラウザではアニメーションの速度が遅くなり(IE6 & 7)、ユーザーがまだアニメーション内にあるときにスライダを再び動かすと混乱します。

新しいブラウザは、ユーザーがスライダの中央アニメーションを動かすと、間違った方向に進行しているように見えることがあります。したがって、updateDiscount()は新しい値で呼び出され、ディレクティブはダウンの代わりにカウントアップします。その結果、アニメーションは間違った方向にカウントされても正しい値に到達しないため、無限ループで間違った方向に移動します。

なぜこのようなことが起こるのか困惑しています。私のsetTimeout()の経験は非常に低く、問題である可能性があります。十分な情報を提供していない場合は、私に知らせてください。

ありがとうございました:)

+1

私は私たちがコードの残りの部分を参照する必要があると思うのparticualriyアニメーションロジック。他のアニメーションがトリガされたときなどにアニメーション化されていることを検出すると、おそらく 'jQuery.stop()'を呼び出す必要があります。また、あなたは何かをタイムアウトさせるような設定をしています...それは、ロジックの中で非常に醜いものです: 'setTimeout(function(){updateDiscount(countUp、totalDiscount);}、1);' – prodigitalson

答えて

0

OKだと思うのために動作するかどうか、私に教えてください

リファクタリング、コードを少し、ここでバグ解決したように思わ最終製品です:

var animationTimeout; 

function recalculateDiscount() { 
    var previousDiscount = parseInt(totalDiscount); 
    totalDiscount = parseInt(calculateDiscount()); 
    if (($.browser.msie && parseFloat($.browser.version) < 9) || $.browser.opera) { 
     $(".totalSavingsHeader").html("$" + totalDiscount); 
    } 
    else { 
     if (previousDiscount != totalDiscount) { 
      clearTimeout(animationTimeout); 
      updateDiscount(totalDiscount); 
     } 
    } 
} 

function updateDiscount(newValue) { 
    var currentValue = parseInt($(".totalSavingsHeader").html().replace("$", "")); 
    if (parseInt(currentValue) === parseInt(newValue)) { 
     clearTimeout(animationTimeout); 
     return; 
    } 
    var direction = (currentValue < newValue) ? "up" : "down"; 
    var htmlValue = direction === "up" ? (currentValue + 1) : (currentValue - 1); 
    $(".totalSavingsHeader").html("$" + htmlValue); 
    animationTimeout = setTimeout(function() { updateDiscount(newValue); }, 5); 
} 
は、

両方のIbuにポイントを与えるだろう& prodigitalson、あなたの助けてくれてありがとう:

1

をここでは、setTimeoutを効率的に

animationTimeout = setTimeout(function { 
    updateDiscount(countUp,totalDiscount); 
},20); 

あなたはevalの使用を避ける無名関数のヘルプを渡しを使用する方法です。

また、1ミリ秒を使用すると速すぎて古いブラウザがフリーズすることがあります。したがって、ユーザーが気付かないほど高いものを使用すると、より効果的に動作することができます。

が...これは、あなたがそれを固定しています

+2

あなたのアニメーションにsetTimeinterval()を使用しないのはなぜですか?このコンテキストではより意味をなさないと思われます – Ibu

+0

ありがとうございますIbu私は今試してみましょう... – timothyclifford

関連する問題