I've got the following variable JS:
/
$(document).ready(function () {
var total = 15.5,
value = 0,
elem = $('div');
var interval = setInterval(function () {
elem.text(value.toFixed(1) + '$');
if (value >= total) {
clearInterval(interval);
}
value = value + 0.1;
}, 5);
});
Two questions:
- The resulting number is
15.6
why? - How can I make the incrementation spend the same amount of time from 0 to the target value? (from 0 to 25 spends the same time as from 0 to 250)
I've got the following variable JS:
http://jsfiddle/c8u8wLsL/13/
$(document).ready(function () {
var total = 15.5,
value = 0,
elem = $('div');
var interval = setInterval(function () {
elem.text(value.toFixed(1) + '$');
if (value >= total) {
clearInterval(interval);
}
value = value + 0.1;
}, 5);
});
Two questions:
- The resulting number is
15.6
why? - How can I make the incrementation spend the same amount of time from 0 to the target value? (from 0 to 25 spends the same time as from 0 to 250)
- "The resulting number is 15.6 why?" Because you increment it one too many times. "How can I make the incrementation spend" Change the increment step.... – epascarello Commented Jan 26, 2015 at 14:27
-
1
It's not safe to rely on floating-point math to be exactly right. When your value gets close to 15.5, it may be very slightly smaller, so the
>=
test could fail. – Pointy Commented Jan 26, 2015 at 14:30 - @Pointy This has nothing to do with rounding error.... It has to do with Order of operations error. – epascarello Commented Jan 26, 2015 at 14:34
-
1
@epascarello well when
value
gets to 15.5, the DOM is updated. Then there's the test forvalue >= total
. Why doesn't it stop at that point? – Pointy Commented Jan 26, 2015 at 14:35 - 1 @cHao Ya but shouldn't update the DIV text – A. Wolff Commented Jan 26, 2015 at 14:38
3 Answers
Reset to default 5You forget to exit from function. Also you should probably update node's text after checking total.
if (value >= total) {
return clearInterval(interval);
}
elem.text(value.toFixed(1) + '$');
fiddle http://jsfiddle/Lqxsh39q/
To solve second problem you can pre-calculate duration of each interval before it setup. And use it like second argument in setInterval. Something like duration = 1000 / (total * 10);
or any formula that you want.
fiddle: http://jsfiddle/Lqxsh39q/1/
@Glen Swift's answer is correct but I have to point out regarding your original code:
You get the resulting number as 15.6 because:
When you think you are getting 15.5 as the result, you are actually getting 15.4999999, which is smaller than 15.5 and hence the if
condition is false even if you think it is true. So it gets incremented once again, giving the final result as 15.6.
As far as the second part is concerned, to get the same time, you need to have the same number of steps for each addition rather than the fixed 0.1
. Let's say you want to reach the target in 100 steps everytime, you can divide the total interval by 100 and then replace it in the code where you are writing 0.1
currently.
The final code should look something like:
$(document).ready(function () {
var total = 15.5,
value = 0,
ment=(total-value)/100,
elem = $('div');
var interval = setInterval(function () {
if (value >= total) {
return clearInterval(interval);
}
elem.text(value.toFixed(1) + '$');
value = value + ment;
}, 5);
});
See the fiddle here
Your existing code:
var interval = setInterval(function () {
elem.text(value.toFixed(1) + '$');
if (value >= total) {
clearInterval(interval);
}
value = value + 0.1;
}, 5);
It should check for the >= total condition first. if condition fails then exit the function.
But you are modifying the text element before the check. thus your error.
This would do.
var interval = setInterval(function () {
value = value + 0.1;
if (value <= total) {
elem.text(value.toFixed(1) + '$');
} else {
clearInterval(interval);
}
}, 5);