使用Javascript动画计数器

时间:2011-07-24 01:01:29

标签: javascript jquery settimeout

我有几个相当简单的javascript函数,可以根据用户操作动画数字的转换,上下移动。页面上有许多滑块,在它们的回调中它们调用recalculateDiscount(),根据它们的选择向上或向下激活数字。

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&amp; 7),如果用户在动画中仍然移动滑块,则会感到困惑。

较新的浏览器在某些情况下效果很好,如果用户在动画中间移动滑块,它似乎开始向错误的方向前进。因此,对于updateDiscount(),使用新值和指令来调用而不是向下计数。结果,动画在无限循环上走错方向,因为当它以错误的方向计数时,它永远不会达到正确的值。

我很难过为什么会发生这种情况,我的setTimeout()体验非常低,这可能是问题所在。如果我没有提供足够的信息,请告诉我。

谢谢:)

2 个答案:

答案 0 :(得分:1)

以下是有效使用setTimeout的方法

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

传递匿名函数可以帮助您避免使用eval。

另外:使用1毫秒,这太快了,有时会冻结旧浏览器。因此,使用更高的,用户甚至不会注意到它可以更好地工作。

让我知道这是否适合您

答案 1 :(得分:0)

好吧认为这是固定的......

稍微重构了一下代码,这里的最终产品看起来已经解决了bug:

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和amp; prodigitalson,谢谢你的帮助:))