Firefox, Opera and Webkit-based browsers have a document-level event DOMContentLoaded that you can listen for with document.addEventListener("DOMContentLoaded", fn, false).
It is more complicated in IE.  What jQuery does in IE is watch onreadystatechange on the document object for a particular readystate with a backup of the document.onload event.  document.onload fires later than the DOM is ready (only when all images have finished loading) so it's only used as a backstop in case the earlier events don't work for some reason.
If you spend some time Googling, you will find code to do this.  I figure the most vetted code to do this is in the large frameworks like jQuery and YUI so, even if I'm not using that framework, I look in their source code for techniques.
Here's the main part of jQuery 1.6.2 source for document.ready():
bindReady: function() {
    if ( readyList ) {
        return;
    }
    readyList = jQuery._Deferred();
    // Catch cases where $(document).ready() is called after the
    // browser event has already occurred.
    if ( document.readyState === "complete" ) {
        // Handle it asynchronously to allow scripts the opportunity to delay ready
        return setTimeout( jQuery.ready, 1 );
    }
    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
        // A fallback to window.onload, that will always work
        window.addEventListener( "load", jQuery.ready, 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", DOMContentLoaded );
        // A fallback to window.onload, that will always work
        window.attachEvent( "onload", jQuery.ready );
        // If IE and not a frame
        // continually check to see if the document is ready
        var toplevel = false;
        try {
            toplevel = window.frameElement == null;
        } catch(e) {}
        if ( document.documentElement.doScroll && toplevel ) {
            doScrollCheck();
        }
    }
},