0

Hi I am trying to get an image to blink using the code below by changing the image. Is there something wrong with my "setTimeout"? TIA

var Test = new Array();
Test.length = 2;

for (var i = 0; i < Test.length; i++) { 
    Test[i] = new Image();
    Test[i].src = "images/Image2" + (i+1) + ".png";
}

function ChangeImage() {
    for (var i = 0; i < Test.length; i++) {
        document.getElementById('Test_Image').src = Test[i].src; 
    }
    setTimeout("ChangeImage()", 1000);           
 }   

 ChangeImage(); 
davidhu
  • 9,523
  • 6
  • 32
  • 53
user1342164
  • 1,434
  • 13
  • 44
  • 83
  • I do not think `src` is being changed... Same `src` is being assigned again and again... – Rayon Oct 14 '16 at 18:15
  • 1
    I believe your setTimeout should be `setTimeout(ChangeImage, 1000);` - no quotes, no `()`. – Tyler Roper Oct 14 '16 at 18:18
  • 1
    `setTimeout()` is not blocking so you schedule `Test.length` `setTimeout()` calls to all run at the exact same time. – jfriend00 Oct 14 '16 at 18:19
  • I tried without quotes still nothing, what do you mean not blocking? – user1342164 Oct 14 '16 at 18:19
  • @user1342164 did you try without `()` as well? `setTimeout` should not include these, and if they're necessary, you must use an anonymous function. – Tyler Roper Oct 14 '16 at 18:20
  • I mean that `setTmeout()` just schedules an activity to run in the future and then the rest of your JS continues to run. It doesn't "wait" until the `setTimeout()` fires before continuing with the rest of your `for` loop. – jfriend00 Oct 14 '16 at 18:20
  • Your function doesn't make sense. You're always going to end up with the last src. – Gavin Oct 14 '16 at 18:22
  • Like this? setTimeout "ChangeImage()", 1000; – user1342164 Oct 14 '16 at 18:22
  • No, I meant like my first comment. `setTimeout(ChangeImage, 1000);` - However, as other commenters have pointed out, I don't see how this function will work - are you trying to change the image once per second? – Tyler Roper Oct 14 '16 at 18:22
  • `setTimeout(ChangeImage, 1000);` This still won't work. You will only ever see the last src because of how fast the code runs. – Gavin Oct 14 '16 at 18:23
  • Thanks Gavin, nothing happening still. – user1342164 Oct 14 '16 at 18:24
  • @user1342164 You're gonna need to outline what you *want* to happen, or what you mean by "blink". Your `ChangeImage` function updates the image src for each iteration of the `for` loop, which happens too fast to even be visible. – Tyler Roper Oct 14 '16 at 18:25
  • ok yes just want to image src to change like every couple seconds, can I change the timeout value? – user1342164 Oct 14 '16 at 18:26
  • @user1342164 you shouldn't use array constructor. It's prefered to use `[]` instead. – Kamil Latosinski Oct 14 '16 at 18:29

4 Answers4

2

First.. you complicated yourself with the new Image() part. You could just use Test[i] = "images/Image2" + (i+1) + ".png";

And for your code, firstly you change the images really fast once every 1 second.

It should be something like this:

function ChangeImage() {
    for (var i = 0; i < Test.length; i++) {
       setTimeout(function(){document.getElementById('Test_Image').src = Test[i]; 
        }, (i+1) *1000);      
    }      

   if(play){
     setTimeout("ChangeImage()", Test.length * 1000);        
   }
}   

This will not halt the javascript code at any point.

After 1 sec it will put image21, after 2 seconds image21 and it will call itself again and it will start all over again;

I put the variable play so you could stop the animation if you wanted.

Mihai Popescu
  • 386
  • 1
  • 11
1

Try something like this.

Edit: Accidentally put setTimeout instead of setInterval. Thanks Santi for point that out.

var Test = new Array();
Test.length = 2;

for (var i = 0; i < Test.length; i++) { 
    Test[i] = new Image();
    Test[i].src = "images/Image2" + (i+1) + ".png";
}

var count = 0;

function ChangeImage() {
  if (count >= Test.length)
    count = 0;
  document.getElementById('Test_Image').src = Test[count].src;  
  count++;   
}   

setInterval(ChangeImage, 1000);
Gavin
  • 4,365
  • 1
  • 18
  • 27
  • This will only happen once. Change the `setTimeout` to be a `setInterval` or put it within the `ChangeImage` function. – Tyler Roper Oct 14 '16 at 18:27
1

setTimeout() is not blocking. That means it only schedules an activity to happen some time in the future and the rest of your Javascript just keeps running. So, you were scheduling Test.length setTimeout() all for the exact same time 1 second from now. Instead, you need to schedule the next image change and then, when that timer fires, you schedule the one after that and so on.

If you just want to cycle through the various images one second apart, you can do this:

function ChangeImage() {
    var cntr = 0;

    function next() {
        if (cntr < Test.length) {
            document.getElementById('Test_Image').src = Test[cntr++].src; 
            // after changing src, schedule next change for 1 second from now
            setTimeout(next, 1000);
        }
    }
    // start first iteration
    next();
 }   

 ChangeImage(); 

You may also need to make sure that all your images are properly preloaded so they display immediately when you set their source. There are numerous ways to make sure the preload is done before starting the rotation such as these:

Image preloader javascript that supports events

How do you cache an image in Javascript

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

Your for loop switches the src once and immediately switches it back, so you can't see it change. Try this instead:

var Test = [];

for (var i = 0; i < 2; i++) {
    Test.push("images/Image2" + (i+1) + ".png");
};

var x = 0;
document.getElementById('Test_Image').src = Test[x];

(function ChangeImage() {
    if(++x >= Test.length) x = 0;
    document.getElementById('Test_Image').src = Test[x];
    setTimeout(ChangeImage, 1000);
})();

EDIT: As Santi pointed out, my original solution only supported two images, while OP requested to loop through an array.

Quangdao Nguyen
  • 1,343
  • 11
  • 25
  • OP seemed to have laid out his solution to loop through an array very intentionally. Your solution works specifically for only two images. – Tyler Roper Oct 14 '16 at 18:30