简体   繁体   中英

Javascript recursion settimeout

I have just started looking at javascript so hopefully this will be something simple. I want to make a slideshow of images that plays automatically. This is very simple, and there are a few tutorials on it but for some reason I haven't been able to get it to work. This is what I have:

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);
}

The image I'm trying to change has id slide. And I also have some evidence that it works. What happens is the first image loads. Then the second image loads (which means the original setTimeout call must be working). Then nothing happens. Which to me suggests it's the recursion that isn't working.

I am very familiar with recursion in other languages, so I think it must just be a syntax thing or something, but I can't seem to figure it out. Thanks for any help.

The problem is that when you pass in strings to be evaluated to the setTimeout call, the evaluation will be done (later, when it's time to fire) in the global context. Thus, you're way better off (for a lot of other reasons) passing in actual functions:

setTimeout(function() { delay(images, 0); }, 2000);

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

In more modern browsers , you can use the .bind() method for functions to create a function that's pre-bound to something to be used as 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);
}

Six of one, half-dozen of the other, but just as an example that shows there are multiple ways to do things.

I would be very suspicious of the second setTimeout call. I would make it clearer by using an explicit function vs. a string expression

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

A bit more compact and passing delay and arguments to setTimeout() :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM