Grace B
Grace B

Reputation: 1406

JavaScript function is sometimes Undefined

I believe this has been asked before but no concrete answer has been determined.

On my website http://euphoricsoftware.com/ there is a fancy countdown script to automatically take you to the normal site, as opposed to mobile or low bandwidth. The script works in every browser with <body onload="setTimeout(countDown(8),1000);"> (where 8 is the number to start from) except sometimes in Chrome the countdown doesn't move and opening the JS console reveals Uncaught ReferenceError: countDown is not defined.

Also on the page is a button which lets you pause and resume the countdown. Resuming calls the countDown() function, too, and even when the undefined error happens onload, if you click the button twice the countdown will work, so it seems to be something to do with onload.

Here's the code I've been using (SO's code format has stuffed up the spacing a bit):

<html>
<head>
    <!-- ... -->
    <script type="text/javascript">
    var stopRedirect = false;
    var back = 0;

    function redirect()
    {
        if (!stopRedirect) {window.location = "home.html";}
    }
    function countDown(num)
    {
        if (!stopRedirect)
        {
            back = num-1;
            if (num < 10)
            {
                document.getElementById("top").innerHTML=num+1;
            }
            document.getElementById("middle").innerHTML=num;
            if (num > 1)
            {
                document.getElementById("bottom").innerHTML=num-1;
                var t = setTimeout("countDown("+(num-1)+")",1000);
            }
            else
            {
                document.getElementById("bottom").innerHTML="&nbsp;";
                document.getElementById("unit").innerHTML=" second&nbsp;";
                var r = setTimeout("redirect()",1000);
            }
        }
    }

    function stop()
    {
        if (!stopRedirect)
        {
            stopRedirect = true;
            document.getElementById("stop").style.display="none";
            document.getElementById("start").style.display="block";
        }
    }
    function start()
    {
        if (stopRedirect)
        {
            stopRedirect = false;
            document.getElementById("stop").style.display="block";
            document.getElementById("start").style.display="none";
            var c = setTimeout("countDown("+(back)+")",1000);
        }
    }
</script>
</head>
<body onLoad="setTimeout(countDown(8),1000);">
    <!-- ... -->

and you can see the site in action at http://euphoricsoftware.com/
Does anyone know why this is happening? Thanks

Upvotes: 0

Views: 1736

Answers (1)

nnnnnn
nnnnnn

Reputation: 150010

I'm not quite sure why you get that error, given that your function is defined in the <head> and you don't try to use it until the onload of the body, but your code does have a problem. This part from your onload="":

setTimeout(countDown(8),1000);

will, when the onload occurs and the code is run, call the countDown() function immediately, passing a parameter of 8, and then take whatever that function returns and pass it to setTimeout() to be executed in 1 second's time. In your case your function doesn't return a particular value, so in effect you are passing undefined to setTimeout().

What you want to do is pass setTimeout() either a function reference or a string.

You can't pass a reference to countDown() directly at the same time as passing a parameter for that function (at least, not with a syntax of setTimeout() that will work in IE), so you would need to wrap it in an anonymous function like this:

onload="setTimeout(function() { countDown(8); }, 1000);"

Or you can use the string format similar to within your countDown() function body (using single-quotes since the onload attribute currently uses doubles):

onload="setTimeout('countDown(8);', 1000)"

Note that the string format is generally frowned upon because it is slower and affects the scope.

Upvotes: 1

Related Questions