I have stored in a vector some values that represent seconds and I need to count down those values showing them at the same time
I have the following code that works correctly to display a countdown
var a = [];
var b = {segundos: 5, elemento: 'demo1'};
a.push(b);
b = {segundos: 7, elemento: 'demo2'};
a.push(b);
var i=0;
function MiFuncionJS()
{
if(a[i].segundos>0)
{
document.getElementById(a[i].elemento).innerHTML = a[i].segundos;
a[i].segundos--;
setTimeout("MiFuncionJS()", 1000);
}
else
document.getElementById(a[i].elemento).innerHTML = "Cuenta finalizada";
}
MiFuncionJS();
<span id="demo1"></span><br>
<span id="demo2"></span><br>
But what I want is to show several accounts at the same time, depending on the stored values, for this I put the function inside a for, as in the following code
var a = [];
var b = {segundos: 5, elemento: 'demo1'};
a.push(b);
b = {segundos: 7, elemento: 'demo2'};
a.push(b);
for(var i=0;i<a.length;i++)
{
(function(i)
{
function MiFuncionJS()
{
if(a[i].segundos>0)
{
document.getElementById(a[i].elemento).innerHTML = a[i].segundos;
a[i].segundos--;
setTimeout("MiFuncionJS()", 1000);
}
else
document.getElementById(a[i].elemento).innerHTML = "Cuenta finalizada";
}
MiFuncionJS();
})(i);
}
<span id="demo1"></span><br>
<span id="demo2"></span><br>
But with this I only get it to show the data once...
When you pass a parameter as string to
setTimeout()
, it will be evaluated at the time the timer runs out, so when the time comes the call will be made in a scope (window
) in which the function you created inside the IIFE is not defined .You must pass as a parameter the function itself created in the way that I indicate below:
In addition,
setTimeout()
it has the problem of not being as precise over time assetInterval()
the first one accumulates the execution time and the second adapts to maintain the configured periodicity by executing the function several times in a row if for some reason they could not be executed. run when the time comes. I recommend you keep usingsetInterval()
.