Cross Browser Dom Ready
Asked Answered
W

3

20

I inherited this piece of code and it seems sub-optimal 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);
Webfooted answered 1/8, 2011 at 17:46 Comment(4)
Put all JS at the end of the document. It is pretty much the same.Beichner
no its not if you have asynchronously loading scripts.Webfooted
If you use async. scripts than you shouldn't use DOMContentLoaded or the way i proposed because the execution of this async. script may occur after this event fired or the HTML-Parser reaches the bottom of the html file. Therefore only window.onload and xhr.onreadystatechange can be used - both is cross browser compatible.Beichner
Regarding blackberry browser. I'm aghast at the amount of bugs I've heard about this particular browser!Ignore
H
62

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

Horme answered 1/8, 2011 at 17:58 Comment(2)
+1 because it's his work that was used by jQuery and he deserves some credit.Ignore
This worked well, as opposed to other smaller snippets that I tried before. Seems to be mature code +1.Projectile
L
5

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() {
  // ... 
})
Luella answered 1/8, 2011 at 18:1 Comment(1)
pretty sure this does not work on blackberry 5. but thanks anyways!Webfooted
D
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);
Discriminant answered 1/8, 2011 at 17:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.