2011-04-05 15 views
7

Acabo de empezar a buscar en Javascript, así que espero que esto sea algo simple. Quiero hacer una presentación de diapositivas de imágenes que se reproduce automáticamente. Esto es muy simple, y hay algunos tutoriales, pero por alguna razón no he podido hacer que funcione. Esto es lo que tengo:Recursión de Javascript settimeout

var image1 = new Image(); 
var image2 = new Image(); 
var image3 = new Image(); 
image1.src = "images/website6.jpg"; 
image2.src = "images/website7.jpg"; 
image3.src = "images/sunset.jpg"; 
var images = new Array(
    "images/website6.jpg", 
    "images/website7.jpg", 
    "images/sunset.jpg" 
); 
setTimeout("delay(images,0)",2000); 
function delay(arr,num){ 
    document.slide.src = arr[num % 3]; 
    var number = num + 1; 
    setTimeout("delay(arr,number)",1000); 
} 

La imagen que intento cambiar tiene una diapositiva de id. Y también tengo alguna evidencia de que funciona. Lo que ocurre es que se carga la primera imagen. Luego se carga la segunda imagen (lo que significa que la llamada setTimeout original debe estar funcionando). Entonces no pasa nada Lo que para mí sugiere que es la recursión que no está funcionando.

Estoy muy familiarizado con la recursividad en otros idiomas, así que creo que debe ser solo una sintaxis o algo así, pero parece que no puedo resolverlo. Gracias por cualquier ayuda.

+0

anule la selección de los parámetros en el segundo setTimeout. esa sería mi primera suposición. – Cronco

+0

@Cronco curiosamente, si hago eso no obtengo la segunda imagen ... lo que sugiere que eso es lo que hace que la imagen cambie una vez. Además, cada ejemplo que he visto tiene comillas, por eso los incluyo. – Paul

+0

El problema al citar las variables es que el temporizador ejecuta la cadena completa '" delay (arr, number) "' en lugar de convertir el variables a sus valores almacenados - por eso no funcionaría el comit (si bien aún tendría que citarlos como así .... '" delay ('"+ arr +"', '"+ number +"') '. Sin embargo, punto discutible: la respuesta de Pointy es mejor. Solo estoy explicando lo que está pasando. –

Respuesta

15

El problema es que cuando transfiere cadenas para ser evaluado a la llamada "setTimeout", la evaluación se realizará (más tarde, cuando sea el momento de disparar) en el contexto global. Por lo tanto, usted es manera mejor (para un montón de otras razones) que pasa en las funciones reales:

setTimeout(function() { delay(images, 0); }, 2000); 
function delay(arr, num) { 
    document.slide.src = arr[num % 3]; 
    setTimeout(function() { delay(arr, num + 1); }, 1000); 
} 

En los navegadores más modernos, puede utilizar el método ".bind()" para las funciones para crear una función eso es pre-atado a algo que se utilizará como this:

setTimeout(delay.bind({arr: images, num: 0}), 2000); 
function delay() { 
    document.slide.src = this.arr[this.num % 3]; 
    setTimeout(delay.bind({arr: this.arr, num: this.num + 1}), 1000); 
} 

Seis de uno, media docena de los otros, pero sólo como un ejemplo que muestra que hay varias maneras de hacer las cosas.

+0

Impresionante, funciona ahora. Todavía estoy un poco confundido acerca de por qué mi código no funcionó. Dices que es evaluado "más tarde" , cuando es hora de disparar ". ¿Cuándo exactamente es esto, y por qué nunca llega a esa parte? Y también ¿por qué el uso de una función anónima cambia esto? Si hay alguna buena documentación que cubra esto, apreciaría un enlace. Gracias. – Paul

+0

El problema es que la cadena, "delay (arr, number)", necesita poder acceder a las variables "arr" a nd "número" para que tenga sentido. Debido a la forma en que funciona la cadena "eval()" (y ahora que lo pienso, no importa si es en el momento de la llamada a setTimeout o posterior), se realiza en un contexto diferente al de la función de tiempo de espera; es solo la forma en que funciona el lenguaje. – Pointy

+0

Cuando utiliza una función ** real **, la interpretación de lo que significa la función ocurre en el alcance real de su llamada a "setTimeout()". Esa función ** no ** tiene acceso a las variables locales allí, de nuevo debido a la forma en que funciona JavaScript. – Pointy

1

Sería muy sospechoso de la segunda llamada setTimeout. Lo aclararía más usando una función explícita vs. una expresión de cadena

setTimeout(function() { delay(arr, number); }, 1000); 
Cuestiones relacionadas