2

I have written this code to change an image:

change = function(){
    for (r=0; r<6; r++){
        for (i = 0; i < 6 ; i++) { 
            setInterval(imgfile(number=i+1), 5000);
        }
    }
}

imgfile= function(number){
    a = 'document.getElementById("imgdiv").src = "images/'+number+'.svg"';
    eval(a);
}

The function change() is called when a button is clicked. When I press the button the image changes straight to 6.svg, when I want it to go through the images 1, 2, 3, 4, 5, 6 and to repeat it 6 times. When I change setInterval to change.setInterval or imgfile.setInterval it doesn't work at all. How do I fix this?

5
  • 1
    Why eval() ? O.o Commented Apr 16, 2017 at 14:52
  • The one rule of eval: don't use eval, because eval is evil. Commented Apr 16, 2017 at 14:53
  • You need to block scope your i variable with the let keyword or wrap it in a closure! Commented Apr 16, 2017 at 14:54
  • 1
    Possible duplicate of How do I add a delay in a JavaScript loop? Commented Apr 16, 2017 at 14:55
  • @MattWebb This change alone isn't enough so the code makes what it is supposed to do Commented Apr 16, 2017 at 14:56

4 Answers 4

2
change = function(i=0){
        imgfile(i%6+1);//change image
         if(i<36) setTimeout(change,5000,i+1);//next image in 5 seconds
}

imgfile= function(number){
    document.getElementById("imgdiv").src = "images/"+number+".svg";//no need to use ev(i||a)l
}

Instead of loop/interval mess you can simply start a timeout that restarts itself after changing the image... This code will loop over 6 images with a delay of 5 seconds and that 6 times...

Sign up to request clarification or add additional context in comments.

Comments

1

Something like this, perhaps?

var index, imgCount, loopCount, imgTag, countdown;

index = 0;
imgCount = 6;
loopCount = 6;
imgTag = document.getElementById('imgdiv');

countdown = function () {
  if (index < imgCount * loopCount) {
    imgTag.src = 'images/' + index % imgCount + '.svg';
    index = index + 1;
    setTimeout(countdown, 5000);
  }
};

countdown();

Here we're avoiding the double loop and using modular math (index % imgCount) to get the right file number.

Comments

0

For another question I wrote a nice utility function that has quite a number of uses, but can also handle this scenario very easily. The main issue is that there is no time elapsing between the different delays being set. So you are setting 6 different actions to all happen within 5000ms, and all will occur at the same moment.

Here's my original answer

Here's the utility function for that answer, along with its application to your problem.

function doHeavyTask(params) {
  var totalMillisAllotted = params.totalMillisAllotted;
  var totalTasks = params.totalTasks;
  var tasksPerTick = params.tasksPerTick;
  var tasksCompleted = 0;
  var totalTicks = Math.ceil(totalTasks / tasksPerTick);
  var initialDelay = params.initialDelay;
  var interval = null;
        
  if (totalTicks === 0) return;
  
  var doTick = function() {
    var totalByEndOfTick = Math.min(tasksCompleted + tasksPerTick, totalTasks);
  
    do {
      params.task(tasksCompleted++);
    } while(tasksCompleted < totalByEndOfTick);
     
    if (tasksCompleted >= totalTasks) clearInterval(interval);
  };
  
  // Tick once immediately, and then as many times as needed using setInterval
  if (!initialDelay) doTick();
  if (tasksCompleted < totalTicks) interval = setInterval(doTick, totalMillisAllotted / totalTicks);
}

// Do 6 actions over the course of 5000 x 6 milliseconds
doHeavyTask({
  totalMillisAllotted: 5000 * 6,
  totalTasks: 6,
  tasksPerTick: 1,
  initialDelay: false, // Controls if the 1st tick should occur immediately
  task: function(n) { console.log('Set image to "images/' + (n + 1) + '.svg"'); }
});

1 Comment

Its always a good idea to overhelm newbies with much code that does not belong to a solution... ;)
-1

You want to do setTimeout().

setTimeout pauses for the millesecond value and then does the code. Where setInterval runs the code every whatever milleseconds.

Yeah, don't do change.setInterval or whatever, it is just setInterval.

An example for you would be this inside the for loop to replace the setInterval function.

setTimeout(imgfile(i+1), 5000);

2 Comments

please dont try to teach things to others that you dont quite understand yourself. setTimeout(imgfile(number=i+1), 5000); will call imgfile right now
Oh I understand, I just put the code he had. But yeah the parameter doesn't make that much sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.