How to feature detect DOMContentLoaded?
I assume you mean in IE, Safari, etc. (browsers that do not support
that event.)
I investigated
document.implementation.hasFeature
document.isSupported
Didn't find anything that looks like it would imply support of
DOMContentLoaded.
The libraries are using Browser detection. It seems that browser
detection fell out of style around 2002, but is now back in style.
It is less viable today than in 2002.
I want to detect support, not browser, so I'd want something like
typeof window.somefeature == "function"
What is it you want to do? If you just want your scripted interface
elements to respond before assets finish loading, that is easy (with
one IE-specific catch.)
Attach a handler to the DOMContentLoaded event (won't hurt browsers
that don't support it) and to the load event. Use a flag to make sure
it doesn't run more than once. Put a script just before the closing
body tag to call this function on a timeout.
This doesn't exactly match DOMContentLoaded as under some
circumstances (eg a page with no assets), your initialization may run
after the page is fully loaded. But if there are assets to download,
it will make your page interactive without waiting around for the load
event. You still need to take care to hide and/or disable interface
elements that will not be functional until after your initialization
runs. And if you have scripts that attach listeners to the load
event, you must take into account that the onload handlers may run
before your simulated DOMContentLoaded event fires. I've never run
into a situation where it is necessary to use the load event (other
than as a fallback for the DOMContentLoaded/timeout solution), but it
would be trivial to add a queue for onload handlers that are run only
after the DOMContentLoaded queue has been processed. You could even
poll document.readyState (if it is detected to be a string) to defer
the processing of the onload queue until the document has completed
loading.
The one caveat for IE is that if you need to append children directly
to the body element, you could get the dreaded "Operation Aborted"
error in IE6. I have never seen this happen using this method with a
10ms delay, but that doesn't mean it is impossible. If you can't
append to a container other than the body, you can poll the innerHTML
property of the body and watch for </body>, at which time it will be
safe to manipulate the body element directly.
Then there is the method used by most of the libraries, which involves
browser sniffing and document.write. They "detect" IE (sometimes with
conditional compilation, sometimes with userAgent parsing), write a
deferred script tag, attach a readystatechange handler to the newly
created element and wait for it to indicate that it has finished
loading. The userAgent parsing will fail for IE imitators,
document.write will fail for XHTML documents and any variation of
behavior in deferred script loading will throw the whole thing off.
And of course, this IE-only method leaves Safari (and others) out, so
an interval is used to poll document.readyState. Typically browser
sniffing is used to "detect" Safari and Konquerer (and nothing else)
before setting this interval, so anything with an unexpected userAgent
string is left waiting around for the load event. And like the other
solution, there is no guarantee that the psuedo-DOMContentReady event
will fire before the load event.