0

I have this function to move an object and I want to set an interval of 500 mil secs on my cycle. No jQuery, just javascript. I have try setInterval('',500)

function shot() {
    document.getElementById('power').play();
    for (var i=140; i<400; i++)
    {  
        document.getElementById('shot').style.visibility='visible';
        imgShot.style.left = parseInt(imgObj.style.left) - 130 + 'px';  
        imgShot.style.top = parseInt(imgObj.style.top) - i + 'px';
        setInterval('',500);
    }           
}
PherricOxide
  • 15,493
  • 3
  • 28
  • 41
CMartins
  • 3,247
  • 5
  • 38
  • 53
  • What do you expect `setInterval('',500);` to do? Do you want to wait 500ms after each iteration in the `for` loop? – gen_Eric Sep 05 '13 at 21:18
  • 1
    Possible duplicate of http://stackoverflow.com/questions/18497092/how-to-pause-a-for-loop-in-javascript-in-a-function – PherricOxide Sep 05 '13 at 21:21
  • I think you want `setTimeout` and increment each iteration by the step. `setTimeout(func, i*500)`. – elclanrs Sep 05 '13 at 21:22

2 Answers2

1

The only way to block sequential execution in JavaScript is to create a busy loop (or use a blocking function like alert): but you do not want to do this as it will freeze the user interface - including updating the UI display of the elements movement!

Instead, structure the code such that it uses asynchronous callbacks - this model allows the browser event loop to continue uninterrupted so that it can react to user input and update the display from the DOM changes.

document.getElementById('power').play();
document.getElementById('shot').style.visibility='visible';

var i = 140;
function moveIt() {
    imgShot.style.left = parseInt(imgObj.style.left) - 130 + 'px';  
    imgShot.style.top = parseInt(imgObj.style.top) - i + 'px';
    i++;
    if (i < 400) {
      // If have more, schedule again in .5s
      // Remember that setTimeout *returns immediately* because it
      // is an asynchronous operation.
      setTimeout(moveIt, 500);
    } else {
      // This will be executed when animation finishes.
    }
}

moveIt();
// This will be executed after first movement which is well before
// the animation finishes. We could also use setTimeout(moveIt, ..) here,
// depending on what is desired.

Or, better, use something like jQuery.animate which takes care of much of the repetitive stuff. (You may have to write a custom easing for this case, because the movement is accelerating linearly from a non-0 initial value along the y-axis.)

setInterval can also be used (just cancel it when done, instead of starting a new timeout), but I find the setTimeout approach slightly easier to show conceptually. The difference is that setInterval will try to always run at time=iteration*timeout, which can - in degenerate cases - be noticeably more consistent than multiple setTimeout calls or, as pointed out Alnitak, it can stack/cascade harmfully.

user2246674
  • 7,621
  • 25
  • 28
  • 1
    actually `setInterval` timeouts can end up stacking, firing lots in immediate sequence. With `setTimeout` that doesn't happen. – Alnitak Sep 05 '13 at 22:27
  • 1
    @Alnitak True; that's the flip side of the coin. I expanded the last sentence to acknowledge your point. – user2246674 Sep 05 '13 at 22:28
0

If you want to run the "shot" function every 500ms,

function shot() {
    document.getElementById('power').play();
    for (var i=140; i<400; i++)
    {  
        document.getElementById('shot').style.visibility='visible';
        imgShot.style.left = parseInt(imgObj.style.left) - 130 + 'px';  
        imgShot.style.top = parseInt(imgObj.style.top) - i + 'px';
    }
}

setInterval(shot,500);

Otherwise if you want to delay each iteration of the for loop, take look at this question that's almost a duplicate: How to pause a FOR loop in Javascript in a function?

Community
  • 1
  • 1
PherricOxide
  • 15,493
  • 3
  • 28
  • 41