partial support for calling onload once the DOM is ready
authorJoey Hess <joey@kitenet.net>
Sun, 19 Oct 2008 19:45:29 +0000 (15:45 -0400)
committerJoey Hess <joey@kitenet.net>
Sun, 19 Oct 2008 19:45:29 +0000 (15:45 -0400)
This adds support for gecko and newer versions of opera
to call onload once the DOM is ready, rather than waiting for
all images in the page to load. Makes relativedate behave
somewhat better.

Dealing with this means jumping into the browser
incompatability waters that I prefer to avoid.
Full solutions for most of the major browsers are listed here:
http://dean.edwards.name/weblog/2006/06/again/

However, no *license* is listed there, so I can't use that code. Also, the more
involved code appears to have various issues (such as the inline IE code not
working via https). So I only added the simple call to a hook needed
for gecko/opera.

It seems that the only standards-compliant way to do this is using the
`defer` attribute to a `script` tag, using an external script that will be
loaded once the DOM is ready, and can call onload. However, that has
browser compatability issues of its own, since not all browsers honor
`defer`.

Perhaps I should really just be using one of the javascript frameworks, that
include code to solve this for the major browsers. But something about them
still puts me off, and this issue is minor enough that I'm willing to live
with incomplete support for now.

underlays/javascript/ikiwiki.js

index 14ddd0745a60abffb28aaec298488a8036d81025..1252f244f8429faab7d5e7dccdd175bdd37a33f7 100644 (file)
@@ -1,9 +1,21 @@
 // ikiwiki's javascript utility function library
 
 var hooks;
 // ikiwiki's javascript utility function library
 
 var hooks;
+
+// Run onload as soon as the DOM is ready, if possible.
+// gecko, opera 9
+if (document.addEventListener) {
+       document.addEventListener("DOMContentLoaded", run_hooks_onload, false);
+}
+// other browsers
 window.onload = run_hooks_onload;
 
 function run_hooks_onload() {
 window.onload = run_hooks_onload;
 
 function run_hooks_onload() {
+       // avoid firing twice
+       if (arguments.callee.done)
+               return;
+       arguments.callee.done = true;
+
        run_hooks("onload");
 }
 
        run_hooks("onload");
 }