Getting notified when the page DOM has loaded (but

2020-02-04 06:17发布

I know there are some ways to get notified when the page body has loaded (before all the images and 3rd party resources load which fires the window.onload event), but it's different for every browser.

Is there a definitive way to do this on all the browsers?

So far I know of:

  • DOMContentLoaded : On Mozilla, Opera 9 and newest WebKits. This involves adding a listener to the event:

    document.addEventListener( "DOMContentLoaded", [init function], false );

  • Deferred script: On IE, you can emit a SCRIPT tag with a @defer attribute, which will reliably only load after the closing of the BODY tag.

  • Polling: On other browsers, you can keep polling, but is there even a standard thing to poll for, or do you need to do different things on each browser?

I'd like to be able to go without using document.write or external files.

This can be done simply via jQuery:

$(document).ready(function() { ... })

but, I'm writing a JS library and can't count on jQuery always being there.

9条回答
Ridiculous、
2楼-- · 2020-02-04 06:58

This works pretty well:

setTimeout(MyInitFunction, 0);
查看更多
神经病院院长
3楼-- · 2020-02-04 07:00

Using setTimeout can work quite well, although when it's executed is up to the browser. If you pass zero as the timeout time, the browser will execute when things are "settled".

The good thing about this is that you can have many of them, and don't have to worry about chaining onLoad events.

setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);

etc.

They will all run when the document has finished loading, or if you set one up after the document is loaded, they will run after your script has finished running.

The order they run in is not determined, and can change between browsers. So you can't count on myFunction being run before anotherFunction for example.

查看更多
手持菜刀,她持情操
4楼-- · 2020-02-04 07:01

The fancy crossbrowser solution you are looking for....doesn't exist... (imagine the sound of a big crowd saying 'aahhhh....').

DomContentLoaded is simply your best shot. You still need the polling technique for IE-oldies.

  1. Try to use addEventListener;
  2. If not available (IE obviously), check for frames;
  3. If not a frame, scroll until no error get's thrown (polling);
  4. If a frame, use IE event document.onreadystatechange;
  5. For other non-supportive browsers, use old document.onload event.

I've found the following code sample on javascript.info which you can use to cover all browsers:

function bindReady(handler){

    var called = false

    function ready() { 
        if (called) return
        called = true
        handler()
    }

    if ( document.addEventListener ) { // native event
        document.addEventListener( "DOMContentLoaded", ready, false )
    } else if ( document.attachEvent ) {  // IE

        try {
            var isFrame = window.frameElement != null
        } catch(e) {}

        // IE, the document is not inside a frame
        if ( document.documentElement.doScroll && !isFrame ) {
            function tryScroll(){
                if (called) return
                try {
                    document.documentElement.doScroll("left")
                    ready()
                } catch(e) {
                    setTimeout(tryScroll, 10)
                }
            }
            tryScroll()
        }

        // IE, the document is inside a frame
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                ready()
            }
        })
    }

    // Old browsers
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    else {
        var fn = window.onload // very old browser, copy old onload
        window.onload = function() { // replace by new onload and call the old one
            fn && fn()
            ready()
        }
    }
}
查看更多
登录 后发表回答