views:

1068

answers:

2

IE has attribute readyState in document object, that indicates current state, e.g. "loading", "complete" etc.

Is there any way to find current loading state of document in Mozilla-based browsers? I'm aware of DOMContentLoaded event, but it wont fit my situation, as my code can be executed after this event was fired.

Added: no, I can't use any framework, and don't confuse with .readyState attribute of XHR object. And it's a bookmarklet, so it can be inserted in at any loading stage.

Added later: Anyway, it looks like it's not a big issue for me. Because this attribute will be added in FF3.6, and it does not break things badly in firefox, when you manipulate on unfinished DOM (unlike IE).

A: 

Can be executed? Just be notified of the DOM event and store its state. I don't see what your root problem is. Surely you could rip out the guts of this method and adapt it to your situation.

jQuery's way of doing it:

// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
 // Use the handy event callback
 document.addEventListener( "DOMContentLoaded", function(){
              //do stuff
 }, false );

// If IE event model is used
} else if ( document.attachEvent ) {
 // ensure firing before onload,
 // maybe late but safe also for iframes
 document.attachEvent("onreadystatechange", function(){
  if ( document.readyState === "complete" ) {
   document.detachEvent( "onreadystatechange", arguments.callee );
   jQuery.ready();
  }
 });

 // If IE and not an iframe
 // continually check to see if the document is ready
 if ( document.documentElement.doScroll && window == window.top ) (function(){
  if ( jQuery.isReady ) return;

  try {
   // If IE is used, use the trick by Diego Perini
   // http://javascript.nwbox.com/IEContentLoaded/
   document.documentElement.doScroll("left");
  } catch( error ) {
   setTimeout( arguments.callee, 0 );
   return;
  }

  // and execute any waiting functions
  jQuery.ready();
 })();
}

// A fallback to window.onload, that will always work
jQuery.event.add( window, "load", jQuery.ready );
Stefan Kendall
This code cannot detect if the document is loaded if it is itself included after the document has loaded (e.g. bookmarklet, dynamic <script> inclusion, etc), in *non*-IE browsers. I believe this is what the OP is asking about.
Crescent Fresh
yes, crescentfresh is right.
maniac
Here's the bug report explaining what I said: http://dev.jquery.com/ticket/4196 Nothing has happened with it for 8 months. :(
Crescent Fresh
+1  A: 

No, it's not possible. Sorry. But here's what you can do. If you can't test for stuff you want to be there before acting:

window.setTimeout(function () {
    // do your stuff here
}, 0);

(This will definitely do it after the page renders, but it might be after onload, not after DOMContentLoaded.)

If you do know how to test for what you're looking for:

(function () {
    if (/* test if what you're looking for is there */) {
        // do your stuff
    } else {
        window.setTimeout(arguments.callee, 0);
    }
})();

This will do it immediately, unless whatever you're looking for is not there, in which case it will wait until after the onload event.

Edit:

Check out this solution.

What it does is, in the edge cases, checks if the last element of document.getElementsByTagName("*") is undefined or not. And that seems to work for him, even in Opera.

Anthony Mills
That will run the function before the DOM is ready in Opera, and may error out in IE as evident here http://stackoverflow.com/questions/1381481/is-checking-for-the-readiness-of-the-dom-overkill/#1382027
Crescent Fresh
It's not perfect, but it's probably the best option, especially if the test version can be implemented. IE is a moot point, since you can check the ready state. I can live with the possible premature running in Opera as the only significant weakness.
Anthony Mills
@Anthony: what I find tricky is that Opera also supports readyState, but it is inconsistent with IE's implementation. For example, if `readyState == "interactive"`, in IE that means you can interact with the DOM (not iframes however) but in Opera the DOM still is not ready! I really would like to figure out a solution to this for all browsers.
Crescent Fresh
@crescentfresh: Check out the solution I found and linked in the above post. I haven't checked, but the guy seems like he develops for Opera a lot.
Anthony Mills
@Anthony: thank you, it works.
maniac
@Anthony: I've yet to try the solution in that link, but from the looks of it it addresses the problem and goes into depth. Great work.
Crescent Fresh
Thanks, crescentfresh!
Anthony Mills