使用 Javascript 制作计数器动画
我有几个相当简单的 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 和 7),并且如果用户在滑块仍在动画内时再次移动滑块,则会感到困惑。
较新的浏览器工作得很好,除了在某些情况下,如果用户在动画中移动滑块,它似乎开始朝错误的方向前进。因此, updateDiscount() 会被调用,并带有一个新值和一个向上计数而不是向下计数的指令。因此,动画在无限循环中走向错误的方向,因为当它以错误的方向计数时,它永远不会达到正确的值。
我很困惑为什么会发生这种情况,我的 setTimeout() 经验非常低,这可能是问题所在。如果我没有提供足够的信息,请告诉我。
谢谢 :)
I have a couple of fairly simple javascript functions which animate the transition of a number, going up and down based on user actions. There are a number of sliders on the page which within their callback they call recalculateDiscount() which animates the number up or down based on their selection.
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);
}
}
The script works really well for the most part however there are a couple of problems. Firstly, older browsers animate more slowly (IE6 & 7) and get confused if the user moves the slider again whilst it is still within the animation.
Newer browsers work great EXCEPT for on some occasions, if the user moves the slider mid-animation, it seems that it starts progressing in the wrong direction. So for updateDiscount() gets called with a new value and a directive to count up instead of down. As a result the animation goes the wrong direction on an infinite loop as it will never reach the correct value when it's counting in the wrong direction.
I'm stumped as to why this happens, my setTimeout() experience is quite low which may be the problem. If I haven't provided enough info, just let me know.
Thank you :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以下是如何有效地使用 setTimeout
传递匿名函数来帮助您避免使用 eval。
另外:使用 1 毫秒,这太快了,有时会冻结旧的浏览器。因此,使用用户甚至不会注意到的更高的值可以更好地工作。
让我知道这是否适合您
Here is how you use setTimeout efficiently
passing an anonymous function help you avoid using eval.
Also: using 1 millisecond, which is too fast and will freeze older browsers sometimes. So using a higher which will not even be noticed by the user can work better.
Let me know if this works out for you
好吧,认为它已经修复了......
稍微重构了代码,这是最终产品,看起来已经解决了错误:
将为 Ibu 和 Ibu 提供积分。 prodigitalson,谢谢您的帮助:)
OK think it's fixed...
Refactored code a little bit, here's final product which looks to have resolved bug:
Will give points to both Ibu & prodigitalson, thank you for your help :)