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.