Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - How to detect if document has loaded (IE 7/Firefox 3)

There's no need for all the code mentioned by galambalazs. The cross-browser way to do it in pure JavaScript is simply to test document.readyState:

if (document.readyState === "complete") { init(); }

This is also how jQuery does it.

Depending on where the JavaScript is loaded, this can be done inside an interval:

var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);
        init();
    }
}, 10);

In fact, document.readyState can have three states:

Returns "loading" while the document is loading, "interactive" once it is finished parsing but still loading sub-resources, and "complete" once it has loaded. -- document.readyState at Mozilla Developer Network

So if you only need the DOM to be ready, check for document.readyState === "interactive". If you need the whole page to be ready, including images, check for document.readyState === "complete".


No need for a library. jQuery used this script for a while, btw.

http://dean.edwards.name/weblog/2006/06/again/

// Dean Edwards/Matthias Miller/John Resig

function init() {
  // quit if this function has already been called
  if (arguments.callee.done) return;

  // flag this function so we don't do the same thing twice
  arguments.callee.done = true;

  // kill the timer
  if (_timer) clearInterval(_timer);

  // do stuff
};

/* for Mozilla/Opera9 */
if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
  document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
  var script = document.getElementById("__ie_onload");
  script.onreadystatechange = function() {
    if (this.readyState == "complete") {
      init(); // call the onload handler
    }
  };
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
  var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      init(); // call the onload handler
    }
  }, 10);
}

/* for other browsers */
window.onload = init;

You probably want to use something like jQuery, which makes JS programming easier.

Something like:

$(document).ready(function(){
   // Your code here
});

Would seem to do what you are after.


if(document.readyState === 'complete') {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

If you actually want this code to run at load, not at domready (ie you need the images to be loaded as well), then unfortunately the ready function doesn't do it for you. I generally just do something like this:

Include in document javascript (ie always called before onload fired):

var pageisloaded=0;
window.addEvent('load',function(){
 pageisloaded=1;
});

Then your code:

if (pageisloaded) {
 DoStuffFunction();
} else {
 window.addEvent('load',DoStuffFunction);
}

(Or the equivalent in your framework of preference.) I use this code to do precaching of javascript and images for future pages. Since the stuff I'm getting isn't used for this page at all, I don't want it to take precedence over the speedy download of images.

There may be a better way, but I've yet to find it.


Mozila Firefox says that onreadystatechange is an alternative to DOMContentLoaded.

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "complete") {
        initApplication();
    }
}

In DOMContentLoaded the Mozila's doc says:

The DOMContentLoaded event is fired when the document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading (the load event can be used to detect a fully-loaded page).

I think load event should be used for a full document+resources loading.