Why does this setTimeout code build up and not terminate?
If you click the body of the html once and wait until the ball is offscreen its fine. However if you clicked 2+ times you'll notice the ball moving faster. When you click the body again to make the ball come back it is still faster then it should be. Why? http://jsfiddle.net/44nwt/10/
-edit- in firefox on my page (i havent tried on jsfiddle) i notice the move func is called repeatably even after the ball has left screen and been remo开发者_运维百科ved. Why isnt it existing?
This works (http://jsfiddle.net/44nwt/11/)
there were two issues:
#1 every click creates another instance of ball and ballwrapper, and adds them into the body. It's only necessary to create the instance if it doesn't already exist. So that would look something like this:
$('body').click(function() {
var wrapper = $('.ballwrapper');
if( wrapper.length == 0 ) {
$('body').append('<div class="ballwrapper"><img class="ball" src="http://michaelreid.typepad.com/.a/6a00e54edabd838833011168a00f09970c-800wi"/></div>');
}
MoveCode();
});
#2 You need a gate at the beginning of your MoveCode function, to prevent the "extra" cycles (the ones that get started by each extra click) from proceeding once the ball/ballwrapper has been removed.
function MoveCode() {
var wrapper = $('.ballwrapper');
if( wrapper.length == 0 ) return;
var l = $('.ball').css("left");
var left = parseInt(l);
if (left > parseInt(wrapper.css('width'))) {
//alert('removed');
wrapper.remove();
return;
}
$('.ball').css("left", (left + 60) + "px");
setTimeout(MoveCode, 160);
}
Also note... I changed it to remove the ballwrapper, rather than removing just the ball. Otherwise, if you run it all the way through over and over again, you'll accumulate old, unused ballwrappers in the background.
if (left > parseInt($('.ballwrapper').css('width'))) {
//alert('removed');
$('.ball').remove();
return;
}
If left is undefined (i.e., the ball has been already removed) then the condition is false and the scheduling will be done repeatedly
精彩评论