Note that I didn't do setTimeout(test(), 9999). I just gave it the name of the function.

With an anonymous function that you construct on the fly, which is what I did in the first code block above.

If you try to do something like setTimeout(test(), 9999), then the browser will first execute test(), and then give the return value to setTimeout. So in your attempt...

setTimeout($('#loading').fadeIn('slow'), 9999);

...the browser was executing that jQuery stuff, fading in the #loading element, and then giving whatever fadeIn returns to setTimeout. As it happens, the fadeIn function returns a jQuery object. But setTimeout doesn't know what to do with objects, so nothing would happen after the 9999 millisecond delay.

setTimeout accepts a function as first parameter - you are currently passing a jQuery selector, which immediately gets evaluated which executes the fadeIn operation. Instead pass in an anonymous function: