2011-11-20 14 views
5

Actualmente estoy tratando de entender un poco de JavaScript.Looping setTimeout

Lo que yo quiero es un texto que se imprimirá en la pantalla seguido de un recuento de un número dado, así:

"Prueba"

[1 seg. pausa]

"1"

[1 seg. pausa]

"2"

[1 seg. pausa]

"3"

Ésta es mis JS:

$(document).ready(function() { 

    var initMessage = "Test"; 
    var numberCount = 4;  

function count(){ 

    writeNumber = $("#target"); 

    setTimeout(function(){ 
     writeNumber.html(initMessage); 
    },1000); 

     for (var i=1; i < numberCount; i++) { 

    setTimeout(function(){ 
     writeNumber.html(i.toString()); 
    },1000+1000*i)}; 

}; 

count(); 

}); 

Ésta es mi marcado:

<span id="target"></span> 

cuando me hacen la página, lo único que consigue es " Prueba "seguido de" 4 ".

No soy genio de JavaScript, por lo que la solución podría ser bastante fácil. Cualquier sugerencia sobre lo que está mal es muy apreciada.

Puede jugar con mi ejemplo aquí: http://jsfiddle.net/JSe3H/1/

Respuesta

6

tiene un problema ámbito de las variables. El contador (i) dentro del bucle solo tiene el alcance de la función count. Para cuando el ciclo ha terminado de ejecutarse, el valor de i es 4. Esto afecta a cada función de setTimeout, por lo que solo verá "4".

Me gustaría reescribir así:

function createTimer(number, writeNumber) { 
    setTimeout(function() { 
     writeNumber.html(number.toString()); 
    }, 1000 + 1000 * number) 
} 

function count(initMessage, numberCount) { 
    var writeNumber = $("#target"); 

    setTimeout(function() { 
     writeNumber.html(initMessage); 
    }, 1000); 

    for (var i = 1; i < numberCount; i++) { 
     createTimer(i, writeNumber); 
    } 
} 

$(document).ready(function() { 

    var initMessage = "Test"; 
    var numberCount = 4; 


    count(initMessage, numberCount); 

}); 

La función createTimer asegura que la variable dentro del bucle es "capturado" con el nuevo alcance que createTimer proporciona.

Ejemplo Actualizado:http://jsfiddle.net/3wZEG/

También puedes ver estas preguntas relacionadas:

+1

Tal vez te gustaría declarar 'writeNumber' ya que es una implícita mundial actualmente. – pimvdb

+0

¡Buena captura! Actualizado. –

+0

¡Muchas gracias por ayudarme! :) – timkl

1

Espero que esto ayude:

 
var c=0; 
var t; 
var timer_is_on=0; 

function timedCount() 
{ 
document.getElementById('target').value=c; 
c=c+1; 
t=setTimeout("timedCount()",1000); 
} 

function doTimer() 
{ 
if (!timer_is_on) 
    { 
    timer_is_on=1; 
    timedCount(); 
    } 
} 
3

En su ejemplo, usted está diciendo "2, 3, 4 y 5 segundos a partir de ahora, respectivamente, escriba el valor de i". Su for-loop habrá pasado todas las iteraciones y establecerá el valor de i en 4, mucho antes de que hayan transcurrido los primeros dos segundos.

Debe crear un cierre en el que se conserve el valor de lo que intenta escribir. Algo como esto:

for(var i = 1; i < numberCount; i++) { 
    setTimeout((function(x) { 
     return function() { 
      writeNumber.html(x.toString()); 
     } 
    })(i),1000+1000*i)}; 
} 

Otro método completamente sería algo como esto:

var i = 0; 
var numberCount = 4; 

// repeat this every 1000 ms 
var counter = window.setInterval(function() { 

    writeNumber.html((++i).toString()); 

    // when i = 4, stop repeating 
    if(i == numberCount) 
     window.clearInterval(counter); 

}, 1000);