Кроссбраузерный дом готов

Я унаследовал этот фрагмент кода, и он кажется неоптимальным и, возможно, неправильным, поскольку он добавляет прослушиватели событий как к объектам окна, так и к объектам документа. Тем не менее, он работает правильно, за исключением BlackBerry 5.0. Может ли кто-нибудь объяснить, правильно ли все это настроено или есть какие-либо рекомендации, чтобы сделать это лучше и/или более упорядоченным?

        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);

person VinnyD    schedule 01.08.2011    source источник
comment
Поместите все JS в конец документа. Это почти то же самое.   -  person Saxoier    schedule 01.08.2011
comment
нет, если у вас асинхронно загружаются скрипты.   -  person VinnyD    schedule 03.08.2011
comment
Если вы используете асинхронность. скрипты, чем вы не должны использовать DOMContentLoaded или способ, который я предложил, потому что выполнение этого async. script может произойти после того, как это событие сработает или HTML-Parser достигнет нижней части html-файла. Поэтому можно использовать только window.onload и xhr.onreadystatechange — оба браузера совместимы.   -  person Saxoier    schedule 03.08.2011
comment
Что касается браузера Blackberry. Я в ужасе от количества ошибок, которые я слышал об этом конкретном браузере!   -  person Camilo Martin    schedule 03.10.2012


Ответы (3)


Если вы хотите узнать, как это делается, или посмотреть, как это сделать. Рекомендую посмотреть работы Диего Перини. Его работа и методы используются во многих библиотеках DOM, включая jQuery. Парень, кажется, не получает много кредита, к сожалению. Он является пионером метода опроса try/catch, который делает возможными кросс-браузерные загруженные события dom, когда IE добавлен в смесь.

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

person chjj    schedule 01.08.2011
comment
+1, потому что это его работа использовалась jQuery, и он заслуживает похвалы. - person Camilo Martin; 03.10.2012
comment
Это сработало хорошо, в отличие от других небольших фрагментов, которые я пробовал раньше. Кажется, зрелый код +1. - person Rolf; 19.01.2014

Если вы хотите использовать чистый javascript, вы можете использовать следующую кроссбраузерную функцию (источник: 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) 
}

Использование:

onReady(function() {
  // ... 
})
person VIK    schedule 01.08.2011
comment
почти уверен, что это не работает на ежевике 5. но все равно спасибо! - person VinnyD; 03.08.2011

Лично я бы использовал для этого jQuery.

jQuery предназначен для обработки множества различных импликаций состояния готовности документа в браузере.

Используя jQuery, ваш приведенный выше код будет выглядеть так:

$(callback);
person Jamie Dixon    schedule 01.08.2011