2009-09-30 28 views
49

Todavía soy nuevo en JQuery, en el camino para hacer funcionar mi ejemplo de ajax me quedé atascado con setTimeout. Lo he desglosado hasta donde debería agregar "." al div cada segundo.JQuery, setTimeout no funciona

El código correspondiente está en dos archivos.

index.html

<html><head> 
<script type='text/javascript' src='jquery.js'></script> 
<script type='text/javascript' src='myCode.js'></script> 
</head> 
<body> 
<div id='board'>Text</div> 
</body> 
</html> 

y myCode.js

(function(){ 
    $(document).ready(function() {update();}); 

    function update() { 
     $("#board").append("."); 
     setTimeout('update()', 1000);  } 
})(); 

el archivo myCode.js funciona bien y "update()" se ejecuta la primera vez que pasa, pero nunca más .

Respuesta

110

Tienes un par de problemas aquí.

En primer lugar, está definiendo su código dentro de un anonymous function. Esta construcción:

(function() { 
    ... 
)(); 

hace dos cosas. Define una función anónima y la llama. Hay razones de alcance para hacer esto, pero no estoy seguro de que sea lo que realmente quiere.

Está pasando en un bloque de código al setTimeout(). El problema es que update() no está dentro del alcance cuando se ejecuta de esa manera. No obstante, si se pasa en un puntero de función en su lugar por lo que este funciona:

(function() { 
    $(document).ready(function() {update();}); 

    function update() { 
    $("#board").append("."); 
    setTimeout(update, 1000);  } 
    } 
)(); 

porque el puntero de función update está dentro de alcance de ese bloque.

Pero como he dicho, no hay necesidad de que la función anónima para que pueda volver a escribir así:

$(document).ready(function() {update();}); 

function update() { 
    $("#board").append("."); 
    setTimeout(update, 1000);  } 
} 

o

$(document).ready(function() {update();}); 

function update() { 
    $("#board").append("."); 
    setTimeout('update()', 1000);  } 
} 

y ambos de estos trabajos. El segundo funciona porque el update() dentro del bloque de código está dentro del alcance ahora.

También prefiero la forma $(function() { ... } bloque acortado y en lugar de llamar setTimeout() dentro update() sólo se puede utilizar en lugar setInterval():

$(function() { 
    setInterval(update, 1000); 
}); 

function update() { 
    $("#board").append("."); 
} 

esperanza que borra eso.

+0

Gracias, funcionó. ¿Alguien puede explicar por qué no funciona de la manera que era? cada ejemplo que he visto es más similar al formato que he usado. –

+0

es w3schools realmente el mejor recurso para hacer referencia a esto? él habría cometido el mismo error si hubiera usado esa página como ejemplo. –

+3

w3schools es correcto en este caso. El problema era un problema de alcance. – cletus

19
setInterval(function() { 
    $('#board').append('.'); 
}, 1000); 

Puede utilizar clearInterval si desea detenerlo en un punto.

+1

No he usado setInverval antes, pero parece ser una ruta más directa para lograr mi objetivo. Gracias –

+0

cletus parecía haberlo agregado a su solución; lo importante es aprender a alimentar una función real para setInterval/setTimeout, no una cadena que se evaluará, por ejemplo, 'update()' –

+2

Pasar un bloque de código como 'update()' es válido pero no preferido. – cletus

8

SetTimeout se utiliza para hacer que su conjunto de código se ejecute después de un período de tiempo especificado, por lo que para sus requisitos es mejor usar setInterval porque eso llamará a su función cada vez en un intervalo de tiempo específico.

+3

No estoy de acuerdo, setTimout es una práctica mejor, en el caso donde la función update() tomó más de 1s para ejecutarse podría tener múltiples instancias de la misma función corriendo al mismo hora. si usa setTimeout, la función update() debe terminar completamente antes de que se produzca el siguiente ciclo de tiempo, por lo tanto, solo se ejecutará 1 instancia a la vez. – kamui

0

Esto logra lo mismo, pero es mucho más simple:

$(document).ready(function() { 
    $("#board").delay(1000).append("."); 
}); 

Usted puede encadenar un retraso antes de que casi cualquier método de jQuery.