parseFloat is doubling operand in animation - javascript

I'm very new to JavaScript and to coding in general. I'm creating an animation that expands and contract an image to simulate breathing. I am also adding a "breath count" to count the number of breaths. This is the code I used to create the breath count:
<h1> Breath Number: <span id= "countingBreaths">0</span> </h1>
Then in the script tag:
//function for breath number increase
var countingTo = function() {
countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));
var startCounting = setInterval(countingTo, 4000);
var stopCounting = function () {
clearInterval(startCounting);
}
stopButton.addEventListener("click", stopCounting);
}
startButton.addEventListener("click", countingTo);
My problem is in the parseFloat function. My intention is to increase the breath number by 1 (+1). But, instead, it is doubling my number (1, 2, 4, 8, 16, 32, etc). I'm not sure what I did wrong. I've tried everything and looked on this site for help but can't find any information. I'd really appreciate the help!

As Pointy wrote in the comment setInterval will create a timer that calls it's function every 4 seconds.
And you start a new timer every time time the function runs, so eventually you have a lot of timers. And each one will increase your breathCount.
Maybe you confused setInterval with setTimeout. Then every function call would only prepare the next one:
var countingTo = function() {
countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));
var startCounting = setTimeout(countingTo, 4000);
…
But you still would add a new click eventListener to your stop button on every function call. That means your stop function would be called a lot of times.
In your example it runs for each created interval.
So you should move that out of your countingTo function like this:
var intervalId = null
var countingTo = function() {
countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));
}
var startCounting = function () {
intervalId = setInterval(countingTo, 4000);
}
var stopCounting = function () {
clearInterval(intervalId);
}
startButton.addEventListener("click", startCounting);
stopButton.addEventListener("click", stopCounting);
Or with setTimeout:
var timeoutId = null
var countingTo = function() {
countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));
timeoutId = setTimeout(countingTo, 4000);
}
var stopCounting = function () {
clearTimeout(timeoutId);
}
startButton.addEventListener("click", countingTo);
stopButton.addEventListener("click", stopCounting);
Also if you are doing animations you might want to look into requestAnimationFrame

Related

change the speed of setInterval in the second round

I am trying to change the speed of the interval for calling a function.
The first time it should take a second, and the rest should take nine seconds to call.
var tiempoCaratula=1000;
var refreshCaratula = setInterval(function() {
$('.col-2').load('caratula.php');
}, tiempoCaratula);
Run the first one using setTimeout and then schedule it for future runs in whatever interval you need to.
var myFunction = function() {
$('.col-2').load('caratula.php');
}
var refreshCaratula;
// call the function after 1000ms
setTimeout(function () {
myFunction();
// then schedule it to run every 9000ms
refreshCaratula = setInterval(myFunction, 9000);
}, 1000);
You could make a timeout that runs once at one second and a sub interval that runs every nine seconds after the timeout.
var tiempoCaratula = 1000;
var tiempoCaratula2 = 9000;
var refreshCaratula = setTimeout(function() {
$('.col-2').load('caratula.php');
var refreshCaratula2 = setInterval(function() {
$('.col-2').load('caratula.php');
}, tiempoCaratula2);
}, tiempoCaratula);

javascript timer counting very fast as time passes

I want a counter which reset in specific interval of time. I wrote this code. When I refresh the page it is executing perfectly. But as time passes the timer goes really fast, skipping seconds. Any idea why this is happening.
function countdown_new() {
window.setInterval(function () {
var timeCounter = $("b[id=show-time]").html();
var updateTime = eval(timeCounter) - eval(1);
$("b[id=show-time]").html(updateTime);
if (updateTime == 0) {
//window.location = ("ajax_chart.php");
$("b[id=show-time]").html(5);
clearInterval(countdown_new());
// countdown_new();
//my_ajax();
}
}, 1000);
}
window.setInterval(function () {
countdown_new();
}, 5000)
HTML
Coundown in 5 seconds
The issue is because you are not clearing the previous timer before starting a new one, so you start a new one for each iteration. To clear the timer you should save a reference to it, and pass that to clearInterval, not a function reference.
Also, note that your pattern of using multiple intervals for different operations can lead to overlap (where two intervals are acting at the same time and cause odd behaviour). Instead, use setTimeout for the initial 5 second delay and then chain further calls to stop this overlap.
Try this:
var timer;
function countdown_new() {
timer = setInterval(function () {
var $showTime = $("#show-time")
var updateTime = parseInt($showTime.text(), 10) - 1;
$showTime.html(updateTime);
if (updateTime == 0) {
$showTime.html('5');
clearInterval(timer);
setTimeout(countdown_new, 5000);
}
}, 1000);
}
setTimeout(countdown_new, 5000);
Example fiddle
Note that you should use the # selector to select an element by its id attribute, and you should never use eval - especially not for type coercion. To convert a value to an integer use parseInt().
You are calling window.setInterval(), which schedules a function call to countdown_new() ever 5 seconds without stop.
Compounding the problem, you are calling countdown_new() again inside your clear interval.
You need to call setInterval just once to continuously execute a function every 5 seconds.
If you want to cancel an interval timer, you need do to this:
var intervalObj = setInterval(function() { ... }, 5000);
clearInterval(intervalObj);
Yes clearinterval does the trick.
function countdown_new(){
t = window.setInterval(function() {
var timeCounter = $("b[id=show-time]").html();
var updateTime = eval(timeCounter)- eval(1);
$("b[id=show-time]").html(updateTime);
if(updateTime == 0){
//window.location = ("ajax_chart.php");
$("b[id=show-time]").html(5);
clearInterval(t);
// countdown_new();
my_ajax();
}
}, 1000);
}

Javascript countdown is getting faster after each run

var i = 3400;
function progress() {
i = 34000;
window.setInterval(function () {
i = i - 100;
document.getElementById("progress").firstChild.data = i;
}, 100);
}
This code is getting faster and faster. The function progress is called every 3 seconds, but I can't change the it's called because it's event based. After around 10 calls i is getting negative!
Umm....
Do not use setInterval
You probably want to use setTimeout
Since progress is called every 3 seconds, you need to avoid that it creates new intervals repeatedly. Using clearTimeout resets the timer anytime you call progress. However, without knowing what exactly you want to achive it's difficult to provide an accurate answer.
var timeout;
function counter(count) {
document.getElementById("progress").firstChild.data = count;
if (count >= 0) {
timeout = window.setTimeout(function() {
counter(count-100);
}, 100);
}
}
function progress() {
window.clearTimeout(timeout);
counter(3400);
}
Try this
var i = 3400;
function progress() {
i = i - 100;
document.getElementById("progress").firstChild.data = i;
window.setTimeout('progress();', 100);
}

Increase the value of a number in an element every x milliseconds

So I have this simple HTML:
<span id="badge">0</span>
I want the number 0 to increase by 1 every x milliseconds. How do I do that with Javascript (with or without jQuery)?
Thanks a bunch - I'm new to this :)
You should do this:
<script>
var $badge = $('#badge'); // cache
setInterval(function () {
var value = parseInt($badge.html());
value++;
$badge.html(value);
}, 1000);
</script>
Assuming 1000 milliseconds.
function increment() {
document.getElementById("badge").value = Number(document.getElementById("badge").value) + 1;
setTimeout("increment()",3000);
}
increment()
Every of the answers I see here has the same drawbacks:
performance issue because of selecting the DOM element every ms cycle. Especially when using a heavy library as jQuery.
setInterval() is probably the tool designed for that functionality, but not reliable. It can diverge a lot from the real time, especially when using a small interval. If you want exactly x executions per second, you may google for some timing libraries.
I would code:
var textNode = document.getElementById(badge).firstChild;
var start = Date.now();
window.setInterval(function update() {
textNode.data = Math.round((new Date()-start)/ms);
}, ms);
If you don't want to start at 0, it will be trivial to add an offset (determined before the loop begins), eg.
var start = Date.now() - (textNode.data * ms || 0); // NaN catching, implicit number cast
Something like this?
var millisecs = 10;
setInterval(function() {
var $badge = $('#badge');
$badge.text(parseInt($badge.text())++);
}, millisecs);
http://jsfiddle.net/iambriansreed/MPP8n/3/
Check this http://www.w3schools.com/js/js_timing.asp
A little more about timers:
// setting a variable for your timer will allow you the ability to "turn it on and off"
var tmrChangeI;
// setTimeout is a function to initiate a function once after given amount of milisecs
// whereas setInterval will continue a function until cancled every so many milisecs
// the following wil "turn on" your timer
tmrChangeI = setInterval(function() {
var $badge = $('#badge');
$badge.html($badge.html() + 1);
}, 500); // 500 will = every half of a second
// to "turn off" timer
clearInterval(tmrChangeI);
// or set a bool to test and use timeout to repeat till bool is false
var tmrBool = true;
// establish function to execute
function tmrFunc() {
var $badge = $('#badge');
$badge.html($badge.html() + 1);
if (tmrBool) tmrChangeI = setTimeout(function() { tmrFunc(); }, 500); // 500 will = every half of a second
};
// execute function, begin timer
tmrChangeI = setTimeout(function() { tmrFunc(); }, 500);
// clear via bool allowing one more execution
tmrBool = false;
// clear by force possibly stoping next execution,
// tho in this manner it may be too late if timer is very short
// and maybe overriden by bool still being true, this is not safest
// but is example of how to use setTimeout
clearTimeout(tmrChangeI);
You can use setInterval.
var $badge = $('#badge');
setInterval(function () {
$badge.html(parseInt($badge.html()) + 1);
}, 1);​//Specify the milliseconds here, right it will update the value every 1 millisecond
Working demo - http://jsfiddle.net/8FMZh/
You could create a Jquery plugin, so you can reuse whenever you need.
$.fn.increment= function(options) {
var $this = $(this);
var coef = options.coef;
var speed = options.speed;
var value = 0;
setInterval(function(){
value = value + coef ;
$this.html(value);
}, speed);
};
And in your main javascript file :
$("#badge").increment({coef: 1, speed:1000});
working demo : http://jsfiddle.net/8FMZh/102/

How to pause/play a Javascript loop when a key is pressed?

Using Javascript/jQuery, how can I pause (or resume) the following loop when the "P" key is pressed?
(function() {
var arr = [...],
len = arr.length;
(function doProcess(i) {
if (i) {
console.log(len - i);
/* do something with arr[len - i] */
setTimeout(function() { doProcess(--i); }, 20000);
}
})(len);
})();
Pausing and resuming is fairly complex. What you really have to do is this:
Start a process and store its timeout ID.
Store the time when you ran that process.
On keypress, clear the timeout using its timeout ID.
Store the unfinished time in another variable.
On next keypress, set the timeout using that unfinished time.
Set the following timeouts to the original intended delay.
Here's a more generalized jsFiddle example I whipped up.
var counterOn = true;
var delay = 3000;
var lastRun;
var tempDelay;
var intervalId;
function decrementCounter() {
// do something
lastRun = new Date();
timeoutId = setTimeout(decrementCounter, delay);
}
function toggleCounter() {
var curTime = new Date();
counterOn = !counterOn;
if (counterOn) {
lastRun = curTime.valueOf() + tempDelay - delay;
timeoutId = setTimeout(decrementCounter, tempDelay);
} else {
clearTimeout(timeoutId);
tempDelay = delay - (curTime.valueOf() - lastRun);
}
}
$(document).keydown(function(e) {
if (e.which === 80) {
toggleCounter();
}
});
decrementCounter();
You'll want to keep track of how much time has passed with your timer (see here: javascript: pause setTimeout();) and call clearTimeout on whatever event you want to stop, then call setTimeout again with your remaining time left once whatever event unpauses is fired again.

Categories