-->

Cross Browser Dom Ready

2020-02-16 18:15发布

问题:

I inherited this piece of code and it seems suboptimal and possibly incorrect since it's adding event listeners on both the window and document objects. However, it is working properly except for blackberry 5.0. Can someone explain if all this is set up correctly or if there are any recommendations to make it better and/or more streamlined?

        if (document.readyState === "complete") 
            callback();
        else if (document.addEventListener) 
        {
            document.addEventListener("DOMContentLoaded",callback,false);
            window.addEventListener("load",callback,false);
        }
        else if(window.attachEvent) 
        {
            document.attachEvent("onreadystatechange", callback);
            window.attachEvent("onLoad",callback);
        } else
            setTimeout(callback,2000);

回答1:

If you want to know how it's done or see a way of doing it. I recommend looking at Diego Perini's work. His work and methods are used in many DOM libraries, including jQuery. The guy doesn't seem to get much credit unfortunately. He is the one who pioneered the try/catch polling method, which is what makes cross-browser dom loaded events possible when IE is thrown into the mix.

https://github.com/dperini/ContentLoaded/blob/master/src/contentloaded.js



回答2:

If you want to use pure javascript, you can use thу following cross-browser function (source (in Russian): http://javascript.ru/unsorted/top-10-functions)

function bindReady(handler){
    var called = false     
    function ready() {
        if (called) return
        called = true
        handler()
    }     
    if ( document.addEventListener ) {
        document.addEventListener( "DOMContentLoaded", function(){
            ready()
        }, false )
    } else if ( document.attachEvent ) { 
        if ( document.documentElement.doScroll && window == window.top ) {
            function tryScroll(){
                if (called) return
                if (!document.body) return
                try {
                    document.documentElement.doScroll("left")
                    ready()
                } catch(e) {
                    setTimeout(tryScroll, 0)
                }
            }
            tryScroll()
        }
        document.attachEvent("onreadystatechange", function(){     
            if ( document.readyState === "complete" ) {
                ready()
            }
        })
    }
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    /*  else  // use this 'else' statement for very old browsers :)
        window.onload=ready
    */
}
readyList = []      
function onReady(handler) {  
    if (!readyList.length) { 
        bindReady(function() { 
            for(var i=0; i<readyList.length; i++) { 
                readyList[i]() 
            } 
        }) 
    }   
    readyList.push(handler) 
}

Usage:

onReady(function() {
  // ... 
})


回答3:

Personally I'd use jQuery for this.

jQuery is designed to handle the variety of different browser implimentations of the document ready state.

Using jQuery your above code would look like:

$(callback);