How to I get setTimeout to work a second time in a chain of functions (instead of making the page freeze)?

StackOverflow https://stackoverflow.com/questions/23122541

Pregunta

So I want to make a chain of functions happen every time I click the body (or any type of element; I’m just using the body for testing, and I have the following code. However, when I click the body a second time, it causes the webpage to freeze. Why is this and how can I fix it?

var doging = false;
var first;
var second;
var third;

$("body").click(function(){
    if(doging == false)
    {
        clearTimeout(first);
        clearTimeout(second);
        clearTimeout(third);
        wow();
    }
});

function wow(){
    doging = true;
    $("#doge_text").text("Wow");
    color();
    size();
    first = setTimeout(function(){wow2();}, 1500);
}

function wow2(){
    $("#doge_text").text("Such doge");
    color2();
    size();
    second = setTimeout(function(){wow3();}, 1500);
}

function wow3(){
    $("#doge_text").text("Very click");
    color3();
    size();
    third = setTimeout(function(){wow4();}, 1500);
}

function wow4(){
    $("#doge_text").text("").css({"height": "0", "width": "0"});
    doging = false;
}
¿Fue útil?

Solución

The problem is that wow4() sets the height and width of the #doge_text element to zero. So, on the second click when you go into size(), w and h are always zero, no matter how big you make the font, thus you get an infinite loop in size().

A fix would be to never enter a sequence with the height or width set to 0. #doge_text must be allowed to resize itself to the text font in order for the size() loop to ever work.

FYI, I was able to zero in on this by just placing console.log() statements throughout the progress. That led me to see that it was getting hung up in the size() function and I then set a breakpoint in that function and stepped through after the second click until I could see that w and h were always zero.

You can fix it by removing the set of height and width to zero in wow4() as they shouldn't be needed because you've already cleared the text:

function wow4(){
    $("#doge_text").text("");
    doging = false;
}

Working example: http://jsfiddle.net/jfriend00/hDvqg/


FYI, there are a couple of odd practices in your code:

  1. You have local variables (only used locally within one function) declared globally such as w and h. These really should be declared as local variables within the function they are used in.

  2. There appears to be no reason to have the clearTimeout() statements at all because you don't have a means of cancelling the timers and once they have executed, there's no reason to cancel them.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top