views:

857

answers:

4

I'm using window.onload to call my JavaScript code that has to be executed after the page is fully loaded. From what I read this is the recommended method to call such scripts.

However, it does not work for some Ajax sites, www.bing.com for instance - window.onload is called before the pages is fully rendered.

Any suggestions?

A: 

I'd recomend using jQuerys $(...).ready() method.

Rasmus Kaj
Isn't it just a wrapper for window.onload ?
Demiurg
No, it does more than just wrap it. It makes sure the DOM is ready. Onload firing is one of the things that has to happen.
Josh Close
I was under impression that "DOM is ready" before window.onload.
Demiurg
+3  A: 

The short answer is that there's no general way to solve this problem (right now).

The definition of a "page" is pretty fungible when AJAX comes into play - it's pretty hard to tell the difference between AJAX that is intended to be part of the initial page load, and that which might not be. So, browsers are left on their own to determine when window.onload() should be fired, and it doesn't always end up where you want.

Luckily, most people don't need a general solution, but rather a specific one. If you care about bing.com, then you can probably look at how bing.com works and design your code to trigger when the site reaches a state that you find acceptable.

Nick Bastin
You are probably right, but there has to be a way, for instance, to check the "onload" event queue somehow and see whether it is empty ?
Demiurg
There is no native "onload" event queue -- each DOM element that can use an onload handler can only use one, and anything akin to a queue has to be implemented in JS. Because of this, and because load order can be implemented in so many ways (as Nick points out), there's unlikely to be a generic solution to this problem.
Ben
Yeah... yet, the browser (according to the status bar) somehow does know when it is ready...
Demiurg
@Demiurg: The status bar doesn't indicate that the page is "ready", it merely indicates that all the objects have been downloaded. That's a far cry from fully initialized and ready to go.
Nick Bastin
A: 

You might be able to listen for changes and requests by globally listening for DOMSubtreeModified and readystatechange events, and use those events instead of the load event for whatever you are trying to do.

Ryan Lynch
A: 

I've wrestled with this a couple of times, and my usual reason for needing some sort of onload event triggering is to be able to interact with the HTML DOM and have getElementById, getElementsByTagName, or various other DOM selectors, return something other than nothing.

Once again, I'm not sure of the exact problem you are trying to solve, but if you must use some sort of onload, and it's because of DOM traversal of some kind, you can cheat a bit with the following sort of code:

window.onload = pageChecker;

function pageChecker() {
    // Onload has fired, but we don't trust it.
    // Check to see if our deepest nested element can be found
    var testElement = document.getElementById("importantElement");

    if ( !testElement ) {
        // Try again in a bit, adjust timeout to what your users
        // can tolerate
        setTimeout(pageChecker, 50);
    }
    else {
        //
        // ... the element exists, run important code below ...
        //
    }
}
jeremyosborne
Thanks, its an interesting trick, but my problem is a bit different - I need to know when the page "looks ready", i.e. from the user perspective.What makes me think that it is possible, at least in theory, is the fact that the browser does know somehow when it is finished - the browser loading indication stops when the page looks ready.
Demiurg
I can see what you're getting at. It is difficult to know when the page really is loaded, unless you know exactly how many images you have, and you track each image that loads with an onload event on each image. In fact, since Image loading is usually the final thing that determines when a page is user-visual-ready, in the current state of the browsers, you just might have to know: how many images are on the page, have all the images loaded? If yes, check that the final element on the page is reachable (some hacksih getElementById). If yes, then page could assume to be loaded.
jeremyosborne
By the way, ajax types of requests (XMLHttpRequest and JSONP like solutions) triggered after a page is really loaded can cause the browser's page load spinner to begin spinning again. I'd think of the state of the page load as more of a binary state: it's either loading something or it's not. And on most AJAX pages, as Nick Bastin said, it's very difficult to say when the page has finished loading. GMail and Yahoo mail, for example, never really stop firing requests and as such it makes the "page loader has stopped spinning, page is loaded" question hard to answer, at least philosophically.
jeremyosborne