Saturday, November 25th, 2006
DOMContentLoaded.Next
Andrea Giammarchi has taken the work of Dean Edwards, Mark Wubben, and Paul Sowden to create his DOMContentLoaded Final Solution.
The work comes with a test page for http and https, and is documented in this function:
- function onContent(callback){ // (C) webreflection.blogspot.com
- // [please note that this code doesn't work]
- // private scope variable
- var IEStringToWrite = // this is IE dedicated string
- "<script defer src='//:' onreadystatechange='
- (function(element){
- // if readystate is complete
- if(element.readyState === "complete")
- // call the global variable
- window.__onContent__();
- })(this);
- '></script>";
- // the above string is necessary to use onreadystatechange property
- // with an undefined page. In this way IE tell us the readyState
- // of the current document
- // to call callback function IE need a global scope variable
- // this variable could call one or more callback
- // then if it's already created we need to call the old callback
- // then this new callback
- window.__onContent__ = (function(oldCallback){
- // returns a function that will delete __onContent__
- // to remove multiple callbacks with different
- // events and different ways for each browser
- return function(){
- // clear __onContent__ as generic function
- window.__onContent__ = function(){};
- // checks if oldCallback isn't null or undefined
- if(oldCallback)
- oldCallback(); // call them to preserve the right order
- callback(); // call this scope callback function
- // (sent calling onContent)
- }
- })(window.__onContent__); // undefined if is the first time we use __onContent__
- // __onContent__ is my function to use as callback
- // I need to add this function as event
- // Opera 9 and FireFox both support DOMContentLoaded as well as
- // addEventListener document method
- if(document.addEventListener)
- document.addEventListener("DOMContentLoaded", __onContent__, false);
- // if some browser supports addEventListener but doesn't support DOMContentLoaded
- // event I don't need to care about that because this event will never be fired
- // at the same time if Safari or KDE one day will support DOMContentLoaded
- // I prefere use this dedicated in-core
- // event instead of next trick that's quite horrible but works with Safari,
- // KDE as Opera 8.5 and lower too
- // that's why I don't use an else if but an if ... because the first time
- // event will be fired __onContent__
- // became an empty function ... then calling them twice is not a problem
- if(
- // Safari and KDE
- /WebKit|Khtml/i.test(navigator.userAgent) ||
- // Opera less than 9
- (window.opera && parseInt(window.opera.version())<9)
- )
- // runtime anonymous function
- (function(){
- // checks if document.readyState is loaded or complete
- /loaded|complete/.test(document.readyState) ?
- // then call __onContent__ , stopping internal loop
- window.__onContent__() :
- // or loops itself with the faster timeout
- setTimeout(arguments.callee, 1);
- })();
- // at this point I've setted the DOMContentLoaded event for every browser
- // but not for Inernet Explorer.
- else if (/MSIE/i.test(navigator.userAgent))
- // I can write dedicated string
- document.write(IEStringToWrite);
- };





3.4 rating from 30 votes
I’ll post a more readable version on my blog in the next few days. But essentially you use
src=//:
instead ofsrc=javascript:void(0)
for the deferred IE script tag.I’m being slightly unfair. The posted code is perfectly readable. :-) It was this code that I saw first:
http://webreflection.blogspot.com/2006/11/my-domcontentloaded-final-solution.html
Hasn’t jQuery had a very good solution based on all the same stuff for a while now?
No.
What’s wrong with the jquery function?
I found using another domloaded function (http://www.thefutureoftheweb.com/blog/2006/6/adddomloadevent) that many IE users got a weird page not accessible error (noted on msdn) and couldn’t view the website (!!). It was from writing something to the document before loaded. Something weird like that. I had to remove it.
For the record this fix is also now a part of Dojo (thanks to Mark Wubben for kicking it off, and Paul showing his solution to the problem).
I shouldn’t have been so brief. :-) I meant that jQuery did not have an HTTPS solution for DOMContentLoaded. It does indeed have a DOMContentLoaded solution as do most of the major libraries now.
Dean and John Resig and others worked together on the DOMContentLoaded function and it has now found its way into most major libraries. This appears to be an improvement and I find generally that if Dean says its an improvement, it is :)
YUI still seems to be the outliar in taking a very different approach toward grabbing nodes when you need them. By simply polling the document for a node, you get onAvailable… and then when you want to know when its content is available, you simply check when it’s nextSibling is available too. See the documentation. Overall, it’s a pretty clever idea.
Hello guys, with a little “perfect” trick, suggested by an anonymous developer, the function now removes itself (I mean the script tag) automatically with one or multiple onContent and only with IE5 or greater (because only IE or compatibles uses script defer).
Thank You for this post, bye :-)
What if to do without window. __ onContent __? For example:
var onContent = (function (aCallback) {
var IEStringToWrite = "";
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded',
aCallback,
false);
}
if (/WebKit|Khtml/i.test(navigator.userAgent) ||
window.opera && parseInt(window.opera.version())
Here’s full code – http://aksus-69.narod.ru/test.html.
Hi people,
I’ve posted an alternative solution for IE that doen’t need the conditional comments. The code there is a bit verbose, but that’s to make it clear. For those who don’t like to put code into comments (UGLY practice if you ask me :D)
See it at: Robert Nyman’s site
Now I now not why nobody thought of this before: the https solution that works with the solution above AND with adding the script through the DOM is dead easy: src=””.
Problem solved :). Tested on my own server and never got that alert again.
I am confused with this part of script
What if we skip the
#
// __onContent__ is my function to use as callback
#
#
// addEventListener document method
#
if(document.addEventListener)
#
document.addEventListener(“DOMContentLoaded”, __onCo
Thanks,
Bob
Agree with Dean. Something wrong with that so need to be fixed